sqlmigrate migraciones migracion makemigrations forzar eliminar datos python django django-migrations

python - migraciones - makemigrations django



Compruebe si hay migraciones Django pendientes (7)

En Django, ¿hay una manera fácil de verificar si todas las migraciones de base de datos se han ejecutado? He encontrado manage.py migrate --list , que me da la información que quiero, pero el formato no es muy legible por la máquina.

Para contexto: tengo un script que no debería comenzar a ejecutarse hasta que la base de datos haya sido migrada. Por diversas razones, sería complicado enviar una señal del proceso que está ejecutando las migraciones. Así que me gustaría que mi script revise periódicamente la base de datos para ver si se han ejecutado todas las migraciones.


1.10 notas de la versión:

La nueva opción makemigrations --check hace que el comando salga con un estado distinto de cero cuando se detectan cambios en el modelo sin migraciones.


Aquí está mi solución de Python para obtener información sobre los estados de migración:

from io import StringIO # for Python 2 use from StringIO import StringIO from django.core.management import call_command def get_migration_state(): result = [] out = StringIO() call_command(''showmigrations'', format="plan", stdout=out) out.seek(0) for line in out.readlines(): status, name = line.rsplit('' '', 1) result.append((status.strip() == ''[X]'', name.strip())) return result

El resultado de esta función se ve así:

[(True, ''contenttypes.0001_initial''), (True, ''auth.0001_initial''), (False, ''admin.0001_initial''), (False, ''admin.0002_logentry_remove_auto_add'')]

Tal vez ayude a algunos de ustedes ...


Lo django_migrations buscando en la base de datos en la tabla django_migrations witch store todas las migraciones aplicadas


Tratar,

python manage.py migrate --list | grep "/[ /]/|^[a-z]" | grep "[ ]" -B 1

devoluciones,

<app_1> [ ] 0001_initial [ ] 0002_auto_01201244 [ ] 0003_auto_12334333 <app_2> [ ] 0031_auto_12344544 [ ] 0032_auto_45456767 [ ] 0033_auto_23346566 <app_3> [ ] 0008_auto_3446677


Actualización :

Si ha actualizado la versión de Django> = 1.11 , use el siguiente comando,

python manage.py showmigrations | grep ''/[ /]/|^[a-z]'' | grep ''[ ]'' -B 1


Usando el código @Ernest, he escrito manage_custom.py para las migraciones pendientes. Puede obtener la lista de migraciones pendientes y también migrar esas migraciones pendientes (solo), por lo tanto, le ahorrará tiempo.

manage_custom.py

__author__ = "Parag Tyagi" # set environment import os import sys import django sys.path.append(''../'') os.environ.setdefault(''DJANGO_SETTINGS_MODULE'', ''settings'') django.setup() from django.core.management import execute_from_command_line from django.db import DEFAULT_DB_ALIAS, connections from django.db.migrations.executor import MigrationExecutor class Migration(object): """ A custom manage.py file for managing pending migrations (only) """ def __init__(self, migrate_per_migration_id=False): """ :param migrate_per_migration_id: Setting this to `True` will migrate each pending migration of any particular app individually. `False` will migrate the whole app at a time. You can add more arguments (viz. showmigrations, migrate) by defining the argument with prefix as ''ARGV_'' and create its functionality accordingly. """ self.ARG_PREFIX = ''ARGV_'' self.MIGRATE_PER_MIGRATION_ID = migrate_per_migration_id self.ARGV_showmigrations = False self.ARGV_migrate = False @staticmethod def get_pending_migrations(database): """ :param database: Database alias :return: List of pending migrations """ connection = connections[database] connection.prepare_database() executor = MigrationExecutor(connection) targets = executor.loader.graph.leaf_nodes() return executor.migration_plan(targets) def check_arguments(self, args): """ Method for checking arguments passed while running the command :param args: Dictionary of arguments passed while running the script file :return: Set the argument variable (''ARGV_<argument>'') to True if found else terminate the script """ required_args = filter(None, [var.split(self.ARG_PREFIX)[1] if var.startswith(self.ARG_PREFIX) else None for var in self.__dict__.keys()]) if any(k in args for k in required_args): for arg in required_args: if arg in args: setattr(self, ''{}{}''.format(self.ARG_PREFIX, arg), True) break else: print ("Please pass argument: {}" "/ne.g. python manage_custom.py {}".format(required_args, required_args[0])) sys.exit() def do_migration(self): """ Migrates all the pending migrations (if any) """ pending_migrations = self.get_pending_migrations(DEFAULT_DB_ALIAS) if pending_migrations: done_app = [] for mig in pending_migrations: app, migration_id = str(mig[0]).split(''.'') commands = [''manage.py'', ''migrate''] + ([app, migration_id] if self.MIGRATE_PER_MIGRATION_ID else [app]) if self.ARGV_migrate and (app not in done_app or self.MIGRATE_PER_MIGRATION_ID): execute_from_command_line(commands) done_app.append(app) elif self.ARGV_showmigrations: print (str(mig[0])) else: print ("No pending migrations") if __name__ == ''__main__'': args = sys.argv migration = Migration() migration.check_arguments(args) migration.do_migration()

Uso:

# below command will show all pending migrations python manage_custom.py showmigrations # below command will migrate all pending migrations python manage_custom.py migrate

PS : Por favor, configure el entorno según la estructura de su proyecto.


./manage.py showmigrations #check que migraciones ya realizadas se han aplicado o no
(o: ./manage.py showmigrations someApp #para aplicación específica solo)

./manage.py makemigrations --dry-run #check para realizar migraciones
(o: ./manage.py makemigrations someApp --dry-run # para una aplicación específica solo)

./manage.py makemigrations #hacer las migraciones
(o: ./manage.py makemigrations someApp #para aplicación específica solo)

./manage.py showmigrations #check que migraciones ya realizadas se han aplicado o no
(o: ./manage.py showmigrations someApp #para aplicación específica solo)

./manage.py sqlmigrate someApp 0001 # ver cambios de SQL para aplicaciones y migraciones específicas

./manage.py migrate #apply migrations
(o: ./manage.py migrate someApp aplicaciones # para aplicaciones específicas solo)

./manage.py showmigrations #check que migraciones ya realizadas se han aplicado o no
(o: ./manage.py showmigrations someApp #para aplicación específica solo)

./manage.py makemigrations --dry-run #check para realizar migraciones
(o: ./manage.py makemigrations someApp --dry-run # para una aplicación específica solo)

PD:
./manage.py migrate someApp zero #unapply todas las migraciones para una aplicación específica


Cáscara

La única solución simple que he encontrado hasta ahora está funcionando.

./manage.py showmigrations | grep ''/[ /]''

que generará una cadena vacía en caso de que se hayan aplicado todas las migraciones.

Sin embargo, está estrechamente vinculado al formato de salida.

Pitón

Verifiqué el código fuente del comando migrate y parece que esto debería hacer el truco:

from django.db.migrations.executor import MigrationExecutor from django.db import connections, DEFAULT_DB_ALIAS def is_database_synchronized(database): connection = connections[database] connection.prepare_database() executor = MigrationExecutor(connection) targets = executor.loader.graph.leaf_nodes() return False if executor.migration_plan(targets) else True # Usage example. if is_database_synchronized(DEFAULT_DB_ALIAS): # All migrations have been applied. pass else: # Unapplied migrations found. pass