예제 #1
0
    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)
예제 #2
0
    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,
                    },
                ],
            })
예제 #3
0
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
예제 #4
0
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
    )
예제 #5
0
    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
예제 #6
0
    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,
                    },
                ],
            })