django migration rename django-south

Cambiar el nombre de una aplicación con Django y South



migration rename (5)

Descargo de responsabilidad: esta respuesta es para aquellos a los que no les importa el historial de migración y que ya han cometido un error al renombrar la aplicación, olvidándose por completo de las migraciones (como yo hice). Trabajó para mi.

Después de cambiar el nombre de la carpeta, tratar todas las importaciones en su código y cambiar el nombre de la aplicación correspondiente en settings.INSTALLED_APPS, simplemente elimine todas las carpetas de migraciones anteriores. Luego haz una inicial como esta

manage.py schemamigration new_app --initial

Luego, al aplicarlo, fingirlo así

manage.py migrate new_app 0001 --fake

No te olvides de probarlo, de lo contrario podrías terminar perdiendo datos

Todas las migraciones posteriores funcionarán bien

manage.py migrate new_app 0002

También puedes eliminar de south_migrationhistory donde app_name = "old_app"

Estoy cambiando el nombre de una aplicación a un nombre más adecuado. Al hacerlo, quiero asegurarme de que South migre apropiadamente la base de datos (renombra las tablas de la base de datos y cambia las referencias en django_content_type o south_migrationhistory). Sé cómo migrar un modelo a una aplicación diferente , pero cuando intento cambiar el nombre de la aplicación, South no reconoce el historial de migración correctamente.

Solución no old_app : al cambiar el nombre de old_app a new_app puedo dejar old_app/migrations intacto y agregar nuevas migraciones a este directorio para migrar la base de datos a la referencia new_app .

Si es posible, preferiría eliminar el directorio old_app completo. Todavía no he pensado en una mejor solución para este problema.

¿Cuál es la mejor manera de cambiar el nombre de una aplicación con Django South sin perder datos?



Es posible cambiar el nombre de una aplicación. Como proyecto de ejemplo, ver:

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

Básicamente, hay 2 migraciones. Primero, las tablas se renombran usando db.rename_table() , y luego se actualizan los tipos de contenido. Esto se puede combinar en una migración comprobando if not db.dry_run: Consulte ¿Cómo migro un modelo de una aplicación django a una nueva? para un ejemplo de eso.

Para las migraciones iniciales, puede cambiar el nombre directamente de las tablas existentes, si están allí:

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.

En el caso de las tablas con más migraciones, es posible que deba verificar si el antiguo nombre de migración ya se aplicó:

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

Por último, recomiendo usar un IDE (por ejemplo, una versión de PyCharm) para renombrar el paquete (clic derecho, refactorizar -> renombrar en el paquete) porque actualizará todos los usos en la aplicación, incluyendo el URLconf, las configuraciones y las importaciones.


Estoy de acuerdo con Laksham en que debes evitar esta situación. Pero a veces, tenemos que hacerlo. He enfrentado esta situación en el pasado y lo he logrado de esta manera.

Si desea evitar la pérdida de datos, puede volcar los datos de la aplicación anterior en un archivo json.

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

Tenga en cuenta la opción --natural que obligará a exportar los tipos de contenido con sus claves naturales (nombre_aplicación, modelo)

Luego puede crear un pequeño comando para abrir este archivo json y reemplazar todas las referencias old_app con new_app.

Algo como esto debería funcionar

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()

A continuación, cambie el nombre de la aplicación, cambie el nombre en INSTALLED_APPS.

Luego, debe eliminar todas las migraciones al sur, regenerar y aplicar una migración inicial para la nueva aplicación. Luego ejecuta el comando SQL:

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

Luego, ejecute una migración hacia el sur para la nueva aplicación a fin de crear las tablas y cargar el archivo json.

python manage.py loaddata old_app.json

He hecho algo similar en un proyecto y parece funcionar bien.

Espero que ayude


No me meteré con los nombres de las aplicaciones. Usted se refiere a los nombres de las aplicaciones literalmente en todas partes. Confs de URL, configuraciones, otras aplicaciones, plantillas, etc.

La forma en que django está diseñado, correspondientemente al sur, asume que no hay necesidad de cambiar los nombres de las aplicaciones. - nombre sus proyectos lo que quiere. No lo mencionas en ninguna parte. Cambiar los nombres de las aplicaciones es engorroso. Su solución indeseable es la mejor solución que veo, si realmente quiere cambiar el nombre de su aplicación.

Por lo que vale, siempre puede usar la import as Python para importar la aplicación con un nombre diferente, si así lo desea.