Tengo una aplicación django con cuatro modelos. Ahora me doy cuenta de que uno de estos modelos debería estar en una aplicación separada. Tengo instalado el sur para migraciones, pero no creo que esto sea algo que pueda manejar automáticamente. ¿Cómo puedo migrar uno de los modelos de la aplicación anterior a uno nuevo?
Además, tenga en cuenta que voy a necesitar que este sea un proceso repetible, para poder migrar el sistema de producción y demás.
django
migration
django-south
Apreche
fuente
fuente
Respuestas:
Cómo migrar usando el sur.
Digamos que tenemos dos aplicaciones: común y específica:
Ahora queremos mover el modelo common.models.cat a una aplicación específica (precisamente a specific.models.cat). Primero realice los cambios en el código fuente y luego ejecute:
Ahora necesitamos editar ambos archivos de migración:
Ahora ambas migraciones de aplicaciones son conscientes del cambio y la vida apesta un poco menos :-) Establecer esta relación entre las migraciones es la clave del éxito. Ahora si lo haces:
hará tanto la migración, y
migrará las cosas hacia abajo.
Tenga en cuenta que para actualizar el esquema usé una aplicación común y para degradar, usé una aplicación específica. Eso es porque la dependencia aquí funciona.
fuente
orm['contenttypes.contenttype'].objects.filter
línea en la parte posterior0003_create_cat
también? También quiero compartir un consejo. Si tiene índices, también deberán modificarse. En mi caso, eran índices únicos, así que mi delantero se ve así:db.delete_unique('common_cat', ['col1'])
db.rename_table('common_cat', 'specific_cat')
db.delete_unique('specific_cat', ['col1'])
orm['contenttypes.contenttype']
, también debe agregar la--freeze contenttypes
opción a susschemamigration
comandos.python manage.py schemamigration specific create_cat --auto --freeze common
para acceder al modelo de gato desde una aplicación común.Para construir sobre Potr Czachur 's respuesta , las situaciones que involucran ForeignKeys son más complicadas y deben ser manejados de forma ligeramente diferente.
(El siguiente ejemplo se basa en las aplicaciones
common
yspecific
referidas en la respuesta actual).luego cambiaría a
Corriendo
generaría las siguientes migraciones (estoy ignorando intencionalmente los cambios de Django ContentType; consulte la respuesta mencionada anteriormente para saber cómo manejar eso):
Como puede ver, el FK debe modificarse para hacer referencia a la nueva tabla. Tenemos que añadir una dependencia por lo que sabemos que el orden en el que se aplicarán las migraciones (y por lo tanto que existirá la mesa antes de tratar de añadir un FK a ella), pero también hay que asegurarse de que se vaya hacia atrás también funciona porque la La dependencia se aplica en la dirección inversa .
Según la documentación del Sur ,
depends_on
se asegurará de que se0004_auto__add_cat
ejecute antes0009_auto__del_cat
al migrar hacia adelante, pero en el orden opuesto al migrar hacia atrás . Si nos fuimosdb.rename_table('specific_cat', 'common_cat')
en laspecific
reversión, lacommon
reversión fallaría al intentar migrar ForeignKey porque la tabla a la que se hace referencia no existiría.Esperemos que esto esté más cerca de una situación del "mundo real" que las soluciones existentes y alguien lo encuentre útil. ¡Salud!
fuente
Los modelos no están muy unidos a las aplicaciones, por lo que moverse es bastante simple. Django usa el nombre de la aplicación en el nombre de la tabla de la base de datos, por lo que si desea mover su aplicación, puede cambiar el nombre de la tabla de la base de datos a través de una
ALTER TABLE
declaración SQL o, incluso más simple, simplemente use eldb_table
parámetro en laMeta
clase de su modelo para referirse a viejo nombre.Si hasta ahora ha utilizado ContentTypes o relaciones genéricas en cualquier parte de su código, probablemente desee cambiar el nombre del
app_label
de contenido que apunta al modelo que se está moviendo, para preservar las relaciones existentes.Por supuesto, si no tiene ningún dato para preservar, lo más fácil es eliminar las tablas de la base de datos por completo y
./manage.py syncdb
volver a ejecutarlas .fuente
Aquí hay una solución más a la excelente solución de Potr. Agregue lo siguiente a específico / 0003_create_cat
A menos que se establezca esta dependencia, South no garantizará que la
common_cat
tabla exista en el momento en que se ejecute / 0003_create_cat específico , arrojando undjango.db.utils.OperationalError: no such table: common_cat
error.South realiza las migraciones en orden lexicográfico a menos que la dependencia se establezca explícitamente. Como se
common
produce antes de quespecific
todas lascommon
migraciones se ejecuten antes del cambio de nombre de la tabla, es probable que no se reproduzca en el ejemplo original que muestra Potr. Pero si cambia el nombrecommon
aapp2
yspecific
haciaapp1
, se encontrará con este problema.fuente
El proceso en el que me he asentado actualmente desde que regresé aquí varias veces y decidí formalizarlo.
Este fue construido originalmente en la respuesta de Potr Czachur y la respuesta de Matt Briançon , utilizando 0.8.4 del Sur
Paso 1. Descubra las relaciones de claves externas infantiles
Entonces, en este caso extendido, hemos descubierto otro modelo relacionado como:
Paso 2. Crear migraciones
Paso 3. Control de origen: Confirmar cambios hasta ahora.
Lo convierte en un proceso más repetible si se encuentra con conflictos de fusión como compañeros de equipo que escriben migraciones en las aplicaciones actualizadas.
Paso 4. Agregar dependencias entre las migraciones.
Básicamente
create_kittycat
depende del estado actual de todo, y todo depende decreate_kittycat
.Paso 5. El cambio de nombre de tabla que queremos hacer.
Paso 6. Solo si necesita al revés () para trabajar Y hacer que un KeyError se ejecute al revés.
Paso 7. Pruébalo: lo que funciona para mí puede no ser suficiente para tu situación de la vida real :)
fuente
Entonces, usar la respuesta original de @Potr anterior no funcionó para mí en South 0.8.1 y Django 1.5.1. Estoy publicando lo que funcionó para mí a continuación con la esperanza de que sea útil para otros.
fuente
Voy a dar una versión más explícita de una de las cosas que Daniel Roseman sugirió en su respuesta ...
Si solo cambia el
db_table
atributo Meta del modelo que ha movido para señalar el nombre de la tabla existente (en lugar del nuevo nombre, Django le daría si lo dejara caer e hiciera unsyncdb
), entonces puede evitar migraciones complicadas del Sur. p.ej:Original:
Después de mudarse:
Ahora solo necesita hacer una migración de datos para actualizar el
app_label
paraMyModel
en ladjango_content_type
tabla y debería estar listo ...Ejecute y
./manage.py datamigration django update_content_type
luego edite el archivo que South crea para usted:fuente