Para un proyecto en Django, tengo que usar dos bases de datos: predeterminada y remota . He creado routers.py
y todo funciona bien.
Había un requisito para crear una tabla en la base de datos remota y creé la migración, la ejecuté y la tabla django_migrations
se creó . Quiero tener solo una tabla django_migrations
, en la base de datos predeterminada.
La parte relevante de routers.py
está aquí:
class MyRouter(object):
# ...
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'my_app':
return db == 'remote'
return None
Ejecuto la migración así:
python manage.py migrate my_app --database=remote
Ahora cuando lo hago:
python manage.py runserver
Me sale la siguiente advertencia:
Tienes 1 migraciones no aplicadas. Es posible que su proyecto no funcione correctamente hasta que aplique las migraciones para las aplicaciones: my_app.
Ejecute 'python manage.py migrate' para aplicarlos.
Las tablas para my_app
se crean en la remote
base de datos y django_migrations
dentro delremote
base de datos, las migraciones se marcan como aplicadas.
EDITAR:
Cómo forzar a Django a usar solo una tabladjango_migrations
, pero aún así aplicar las migraciones a diferentes bases de datos?
¿Cómo aplicar las migraciones en diferentes bases de datos para que no se generen advertencias?
fuente
django_migrations
tabla compartida , será necesario diferenciar entre filas con migraciones paradefault
yremote
db. Esto es bastante profundo en las partes internas de django. Incluso me arriesgaría a afirmar que requeriría una gran reescritura del código de migración.Respuestas:
Gracias a los comentarios sobre mi pregunta, investigué un poco y obtuve los siguientes hallazgos.
El uso de múltiples bases de datos da como resultado la creación de una tabla
django_migrations
cuando se utilizan migraciones. No hay opción para registrar las migraciones en una sola tabladjango_migrations
, como explica el comentario de Kamil Niski . Esto queda claro después de leer el archivodjango/db/migrations/recorder.py
.Ilustraré un ejemplo con un proyecto
foo
y una aplicaciónbar
dentro del proyecto. La aplicaciónbar
solo tiene un modeloBaz
.Creamos el proyecto:
Ahora tenemos estos contenidos dentro del directorio principal del proyecto:
Tengo la costumbre de agrupar todas las aplicaciones dentro del directorio del proyecto:
En el archivo
foo/settings.py
ajustamos la configuración para usar dos bases de datos diferentes, para los propósitos de este ejemplo usamossqlite3
:Ahora ejecutamos las migraciones:
Esto ejecuta todas las migraciones, la parte
--database=default
es opcional, porque si no se especifica, Django usa la base de datos predeterminada.Django ha aplicado todas las migraciones a la base de datos predeterminada:
Ahora creamos el modelo
Baz
:models.py
:registrar la aplicación
bar
enINSTALLED_APPS
(foo/settings.py
) y crearlas:Antes de ejecutar las migraciones que creamos
routers.py
dentro de labar
aplicación:y regístralo en
foo/settings.py
:Ahora, el enfoque ingenuo sería ejecutar las migraciones
bar
en laremote
base de datos:Las migraciones se han aplicado a la
remote
base de datos:Cuando corremos:
se generará la siguiente advertencia:
Sin embargo, todo parece funcionar bien. Sin embargo, no es satisfactorio tener esta advertencia.
La forma correcta sería ejecutar todas las migraciones para cada base de datos como se sugiere en esta respuesta .
Se vería así:
y después de crear las migraciones para
bar
:El enrutador se encargará de que la tabla
bar_baz
se cree solo en laremote
base de datos, pero Django marcará las migraciones aplicadas en ambas bases de datos. También las mesas paraauth
,admin
,sessions
, etc. serán creados sólo en ladefault
base de datos, como se especifica enrouters.py
. La tabladjango_migrations
en laremote
base de datos también tendrá registros para estas migraciones.Es una lectura larga, pero espero que arroje algo de luz sobre esto, en mi opinión, no se explica a fondo el problema en la documentación oficial .
fuente