django - makemigrations - reset all migrations
Django 1.8: Crear migraciones iniciales para el esquema existente (5)
Finalmente lo puse a trabajar, aunque no sé por qué y espero que funcione en el futuro.
Después de hacer numerosas pruebas y visitar el sitio de desarrollo de Django (
link
).
Estos son los pasos (para quien tenga este problema):
-
Vaciar la tabla
django_migrations
:delete from django_migrations;
-
Para cada aplicación, elimine su carpeta de
migrations
:rm -rf <app>/migrations/
-
Restablezca las migraciones para las aplicaciones "integradas":
python manage.py migrate --fake
-
Para cada aplicación ejecutada:
python manage.py makemigrations <app>
. Tenga cuidado con las dependencias (los modelos con ForeignKey deben ejecutarse después de su modelo principal). -
Finalmente:
python manage.py migrate --fake-initial
Después de eso ejecuté el último comando sin el
--fake-initial
, solo para asegurarme.
Ahora todo funciona y puedo usar el sistema de migraciones normalmente.
Estoy seguro de que no soy el único que se encuentra con este problema. Debe documentarse mejor e incluso simplificarse.
Actualización para usuarios de Django 1.9:
Tuve este escenario nuevamente con un Django 1.9.4, y el paso 5 falló.
Todo lo que tuve que hacer es reemplazar
--fake-initial
con
--fake
para que funcione.
Comencé un proyecto django 1.8, que usa el sistema de migraciones.
De alguna manera en el camino las cosas se complicaron, así que borré las carpetas y la tabla de migraciones del DB, y ahora estoy tratando de reconstruirlas, sin éxito.
Tengo tres aplicaciones (3 archivos de
models.py
), ¡y los modelos reflejan las tablas EXACTAMENTE!
El mejor enfoque que he encontrado hasta ahora fue:
-
Borra todas
migrations
carpetas demigrations
. ¡Hecho! -
Eliminar todo de la tabla
django_migrations
. ¡Hecho! -
Ejecute
python manage.py makemigrations --empty <app>
para cada aplicación. ¡Hecho! -
Ejecute
python manage.py migrate --fake
. ¡Hecho! (aunque solo funciona si lo ejecuto después de cada comandomakemigrations
.
Ahora agrego un nuevo campo, ejecuto el comando
makemigrations
y recibo el siguiente error:
django.db.utils.OperationalError: (1054, "Unknown column ''accounts_plan.max_item_size'' in ''field list''")
He estado quemando HORAS en esta cosa. ¿Cómo demonios puedo inicializar las migraciones para poder seguir trabajando sin interrupciones de migración cada vez?
¿Por qué es tan complicado?
¿Por qué no hay una línea simple:
initiate_migrations_from_schema
?
EDITAR:
Ahora las cosas se ponen aún más desagradables.
django_migrations
tabla
django_migrations
y
django_migrations
toda la carpeta de
migrations
.
Ahora trato de ejecutar
python manage.py migrate --fake-initial
(algo que encontré en los documentos DEV), solo para configurar todas las aplicaciones ''internas'' de Django (autenticación, sesión, etc.) y obtengo:
(1054, "Unknown column ''name'' in ''django_content_type''")
.
Ahora, esta "columna" no es una columna real.
Es una
@property
definida en la aplicación de
@property
de
contenttypes
de Django.
¿QUE ESTA PASANDO AQUI?
¿Por qué identifica la propiedad de
name
como una columna real?
Gracias. He estado trabajando en este problema por un tiempo y su lista de mejores prácticas fue realmente útil. Potencialmente, esto puede ayudar a los novatos a Python como yo:
Si está comenzando con un conjunto de modelos existente, borre cualquier migración anterior que haya realizado.
Mi situación fue que comencé con sqlite solo para comprender django y luego cambié a un mysql db, y seguía arrojando un error 1053, probablemente tratando de aplicar una migración anterior que no tenía los recursos para resolver ...
Me he encontrado con este escenario, pero nunca he tenido que soltar la base de datos para resolverlo. Por lo general, elimino la carpeta de migraciones de la aplicación y elimino las entradas de migración de la base de datos.
Intentaría ejecutar migraciones una aplicación a la vez. Si alguna de las aplicaciones se basa en otras tablas, obviamente agréguelas al final.
Además, generalmente solo ejecuto python manage.py makemigrations y luego solo python manage.py migrate Incluso con la migración inicial, debería funcionar bien con Django 1.7 y 1.8.
Si está utilizando enrutadores, podría ser un problema allí.
Verifique el método
allow_migrate
si se ejecuta correctamente en
routers.py
.
Intente establecer que el valor de retorno sea siempre
True
y verifique si resuelve el problema,
def allow_migrate(self, db, app_label, model_name=None, **hints):
return True
django ..., 1.8, 1.9, ...
Lo que desea lograr es aplastar las migraciones existentes y usar el reemplazo para ellas.
Cómo hacerlo correctamente sin usar ningún comando al liberar (un caso sin impacto en la base de datos y los compañeros de trabajo).
-
Para cada aplicación, elimine su carpeta de migraciones:
mv <app>/migrations/ <app>/migrationsOLD/
-
Para cada aplicación que ejecute:
python manage.py makemigrations <app>
. -
Personaliza cada nueva migración:
-
si tiene una aplicación compleja , o más aplicaciones y modelos relacionados entre ellas, para evitar
CircularDependencyError
oValueError: Unhandled pending operations for models
:prepare la segunda migración vacía en
<app>
0002_initial2.py
(coloque allí la dependencia deapp_other::0001_initial.py
y<app>
::0001_initial.py
también - todos los ForeignKey, M2M relacionados con modelos creados en el paso de migración 0001 en otras aplicaciones)Todo debe estar en orden, a veces requerirá más migraciones para prepararse. Tenga cuidado con el atributo de
dependencies
aquí en cada migración. -
tenga cuidado con los valores iniciales: verifique usted mismo todas
RunPython
accionesRunPython
demigrationsOLD
y copie el código a la nueva migración inicial si es necesario. -
(opcional para
--fake-initial
) Addinitial=True
a todas las nuevas clases de migración (0002 también si se agregó). -
Agregar
replaces
atributo en nueva clase de migración. (como la propia costumbre de unasquashmigrations
). Ponga allí todas las migraciones antiguas de<app>
-
-
Verifique todo con
makemigrations
.afirmar "No se detectaron cambios"
-
Compruebe si
migrate -l
show [x] en todas partesafirmar similar:
[X] 0001_inicial
[X] 0002_initial2 (102 migraciones aplastadas)
Ejemplo:
Para los viejos:
0001_initial.py
0002_auto.py
...
0103_auto.py
preparar:
0001_initial.py
0002_initial2.py (optional but sometimes required to satisfy dependency)
y agregar a
replaces
al último (0002 aquí, puede ser 0001):
replaces = [(b''<app>'', ''0002_auto.py''), ..., (b''<app>'', ''0103_auto.py'')]
0001_initial.py debe nombrarse de la misma manera que el anterior.
0002_initial2.py es nuevo, pero es un reemplazo para las migraciones antiguas, por lo que Django lo tratará como cargado.