def handle(self, *args, **options): # Get the database we're operating from db = options['database'] connection = connections[db] # Hook for backends needing any database preparation connection.prepare_database() # Detect mid-project installation recorder = MigrationRecorder(connection) if (_has_table(recorder) and recorder.migration_qs.filter(app='auth').exists() and not recorder.migration_qs.filter( app='user_unique_email').exists()): # Auto fake initial migration migrations = [ recorder.Migration(app='user_unique_email', name='0001_initial') ] + [ recorder.Migration(app=m.app, name=m.name) for m in recorder.migration_qs.iterator() ] recorder.flush() recorder.migration_qs.bulk_create(migrations) # Go on with normal migrate command return super().handle(*args, **options)
def test_add_recorded_migration(self): """Testing MigrationList.add_recorded_migration""" recorded_migration1 = MigrationRecorder.Migration( app='tests', name='0001_initial', applied=True) recorded_migration2 = MigrationRecorder.Migration( app='tests', name='0002_add_field', applied=True) migration_list = MigrationList() migration_list.add_recorded_migration(recorded_migration1) migration_list.add_recorded_migration(recorded_migration2) self.assertEqual( migration_list._by_id, { ('tests', '0001_initial'): { 'app_label': 'tests', 'name': '0001_initial', 'migration': None, 'recorded_migration': recorded_migration1, }, ('tests', '0002_add_field'): { 'app_label': 'tests', 'name': '0002_add_field', 'migration': None, 'recorded_migration': recorded_migration2, }, }) self.assertEqual( migration_list._by_app_label, { 'tests': [ { 'app_label': 'tests', 'name': '0001_initial', 'migration': None, 'recorded_migration': recorded_migration1, }, { 'app_label': 'tests', 'name': '0002_add_field', 'migration': None, 'recorded_migration': recorded_migration2, }, ], })
def _get_migrations(included_apps): """ Get migrations for included apps. """ migration_objects = [] for app_config in apps.get_app_configs(): if app_config.name not in included_apps: continue app_label = app_config.label module_name, _ = MigrationLoader.migrations_module(app_label) if module_name is None: continue try: module = import_module(module_name) except ImportError: continue directory = os.path.dirname(module.__file__) for name in os.listdir(directory): if name.endswith(".py"): import_name = name.rsplit(".", 1)[0] if import_name[0] not in "_.~": migration_objects.append( MigrationRecorder.Migration(app=app_label, name=import_name)) return migration_objects
def record_applied_migrations(connection, migrations): """Record a list of applied migrations to the database. This can only be called when on Django 1.7 or higher. Args: connection (django.db.backends.base.BaseDatabaseWrapper): The connection used to record applied migrations. migrations (MigrationList): The list of migration targets to record as applied. """ assert supports_migrations, \ 'This cannot be called on Django 1.6 or earlier.' recorder = MigrationRecorder(connection) recorder.ensure_schema() recorder.migration_qs.bulk_create( recorder.Migration(app=info['app_label'], name=info['name']) for info in migrations )
def applied_migrations(self): """The migrations already applied. This will contain both the migrations applied from the database and any set in :py:attr:`extra_applied_migrations`. """ extra_migrations = self.extra_applied_migrations if isinstance(self._applied_migrations, dict): # Django >= 3.0 applied_migrations = self._applied_migrations.copy() for info in extra_migrations: app_label = info['app_label'] name = info['name'] recorded_migration = info['recorded_migration'] if recorded_migration is None: recorded_migration = MigrationRecorder.Migration( app=app_label, name=name, applied=True) applied_migrations[(app_label, name)] = recorded_migration elif isinstance(self._applied_migrations, set): # Django < 3.0 applied_migrations = self._applied_migrations | set( (info['app_label'], info['name']) for info in extra_migrations ) else: raise DjangoEvolutionSupportError( 'Migration.applied_migrations is an unexpected type (%s)' % type(self._applied_migrations)) return applied_migrations
def test_update(self): """Testing MigrationList.update""" if supports_migrations: migration1 = InitialMigration('0001_initial', 'tests') migration2 = AddFieldMigration('0002_add_field', 'tests') recorded_migration1 = MigrationRecorder.Migration( app='tests', name='0001_initial', applied=True) recorded_migration2 = MigrationRecorder.Migration( app='tests', name='0002_add_field', applied=True) else: migration1 = None migration2 = None recorded_migration1 = None recorded_migration2 = None migration_list1 = MigrationList() migration_list1.add_migration_info( app_label='tests', name='0001_initial', migration=migration1, recorded_migration=recorded_migration1) migration_list1.add_migration_info( app_label='tests', name='0002_add_field', migration=None, recorded_migration=None) migration_list2 = MigrationList() migration_list2.add_migration_info( app_label='tests', name='0002_add_field', migration=migration2, recorded_migration=recorded_migration2) migration_list2.add_migration_info( app_label='foo', name='0001_initial') migration_list1.update(migration_list2) self.assertEqual( migration_list1._by_id, { ('tests', '0001_initial'): { 'app_label': 'tests', 'name': '0001_initial', 'migration': migration1, 'recorded_migration': recorded_migration1, }, ('tests', '0002_add_field'): { 'app_label': 'tests', 'name': '0002_add_field', 'migration': migration2, 'recorded_migration': recorded_migration2, }, ('foo', '0001_initial'): { 'app_label': 'foo', 'name': '0001_initial', 'migration': None, 'recorded_migration': None, }, }) self.assertEqual( migration_list1._by_app_label, { 'foo': [ { 'app_label': 'foo', 'name': '0001_initial', 'migration': None, 'recorded_migration': None, }, ], 'tests': [ { 'app_label': 'tests', 'name': '0001_initial', 'migration': migration1, 'recorded_migration': recorded_migration1, }, { 'app_label': 'tests', 'name': '0002_add_field', 'migration': migration2, 'recorded_migration': recorded_migration2, }, ], })