32 votes

Renommer une application avec Django et Sud

Je suis renommer une demande pour un nom plus approprié. En agissant de la sorte, je veux m'assurer que le Sud correctement migre la base de données (renomme tables de base de données et les changements de références dans django_content_type ou south_migrationhistory). Je sais comment migrer d'un modèle à une autre application, mais quand j'ai essayer de renommer l'application elle-même, Sud ne pas reconnaître l'histoire de la migration correctement.

Indésirables solution: renommer old_app de new_app j'ai pu quitter old_app/migrations intact, et ajouter de nouvelles migrations à ce répertoire pour migrer la base de données de référence new_app.

Si possible, je préfère supprimer le répertoire old_app entièrement. Je n'ai pas encore pensé à la meilleure solution à ce problème.

Quelle est la meilleure façon de renommer une application avec Django Sud sans perdre de données?

45voto

luc Points 13564

Je suis d'accord avec Laksham que vous devriez éviter cette situation. Mais parfois, nous avons à la. Je fais face à cette situation et de procéder de cette façon.

Si vous voulez éviter de perdre des données, vous pouvez vider le vieux données d'application dans un fichier json.

python manage.py dumpdata old_app --natural --indent=4 1> old_app.json

Remarque l' --option naturelle qui va forcer les types de contenus peuvent être exportés avec leur naturel touches (app_name, modèle)

Ensuite, vous pouvez créer une petite commande pour ouvrir ce fichier json et à remplacer tous les old_app références avec les new_app.

Quelque chose comme cela devrait fonctionner

class Command(BaseCommand):
    help = u"Rename app in json dump"

    def handle(self, *args, **options):
        try:
            old_app = args[0]
            new_app = args[1]
            filename = args[2]
        except IndexError:
            print u'usage :', __name__.split('.')[-1], 'old_app new_app dumpfile.json'
            return

        try:
            dump_file = open(filename, 'r')
        except IOError:
            print filename, u"doesn't exist"
            return

        objects = json.loads(dump_file.read())
        dump_file.close()

        for obj in objects:
            obj["model"] = obj["model"].replace(old_app, new_app, 1)

            if obj["fields"].has_key("content_type") and (old_app == obj["fields"]["content_type"][0]):
                obj["fields"]["content_type"][0] = new_app

        dump_file = open(filename, 'w')
        dump_file.write(json.dumps(objects, indent=4))
        dump_file.close()

Puis renommer l'application, modifiez le nom dans INSTALLED_APPS.

Ensuite, vous devez supprimer tous les migrations sud, à régénérer et à appliquer une première migration pour la nouvelle application. Puis exécuter la commande SQL:

update django_content_type set app_label='new_app' where app_label='old_app'

Ensuite, lancez une sud migrent pour la nouvelle application, afin de créer les tables et charger le fichier json.

python manage.py loaddata old_app.json

J'ai fait quelque chose de similaire sur un projet et il semble fonctionner ok.

J'espère que cela aide

24voto

vdboor Points 6259

Il est possible de renommer une application. Comme exemple de projet, voir:

https://github.com/ASKBOT/django-south-app-rename-example

Fondamentalement, il y a 2 migrations. D'abord les tables sont renommés à l'aide d'un db.rename_table(), et suivant les types de contenu sont mis à jour. Cela peut être combinée à une migration en vérifiant if not db.dry_run:. Voir Comment migrer d'un modèle d'un django app et dans un nouveau? pour un exemple.

Pour un premier migrations, vous pouvez renommer directement les tables existantes, si elles sont là:

if 'old_app_table_name' in connection.introspection.table_names():
    db.rename_table('old_app_table_name', 'new_app_table_name')
else:
    # Create new app tables directly.

Pour les tables avec plus de migrations, vous devrez peut-être vérifier si l'ancien nom de migration a déjà été appliquée:

from south.models import MigrationHistory
if MigrationHistory.objects.exists(app_name='old_app', migration='0001_initial'):
    return

Enfin, je vous recommande d'utiliser un IDE (par exemple, un PyCharm d'essai) pour renommer l'archive (clic droit, refactor -> renommer sur le paquet), car elle sera mise à jour tous les usages à travers l'application pour vous, y compris l'URLconf, les paramètres et les importations.

8voto

jamesmfriedman Points 306

Après avoir branché, je suis venu avec cela. Devrait en prendre soin. https://gist.github.com/jamesmfriedman/6168003

-6voto

Lakshman Prasad Points 24002

Je ne plaisante pas avec les noms d'application. Vous vous référez à l'application des noms littéralement partout. URL confs, paramètres, d'autres applications, des modèles, etc.

La façon dont il est conçu, en conséquence du sud, suppose il n'est pas nécessaire de changer les noms des applications. - nom de vos projets, ce que vous voulez. Vous ne vous parle pas de n'importe où. Changer les noms des applications, c'est encombrant. Votre indésirable solution est la meilleure solution que je vois, si vous voulez vraiment changer le nom de votre application.

Pour ce qu'il vaut, vous pouvez toujours utiliser le python import as à l'importation de l'application dans un autre nom, si vous le désirez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X