1

假设您正在开发一个 Django 项目,其中有几个人使用(例如)git。当你这样做时,git pull你可能会得到一些南迁移,但是,你可能没有注意到(出于某种原因)。然后当你继续开发时,你可能会遇到 python 异常,因为你没有进行迁移。现在有时可能需要一段时间才能发现自己忘记了这一点,这很烦人。

所以我在想,South 不能检测到你没有完成所有的迁移,如果是的话就抛出一个异常?

我想这可能是一个设置,如果你想在不进行迁移的情况下继续开发,你可以关闭它。

4

2 回答 2

3

好吧,这就是我的方式。

我有一个south_test包含 3 个迁移的应用程序,即“python manage.py migrate --list”显示:

south_test
  (*) 0001_initial
  (*) 0002_auto__add_person
  ( ) 0003_auto__add_field_person_age

那是(不太)魔术代码:

from south.models import MigrationHistory
from south.migration import Migrations

all_migrations = Migrations('south_test')
applied_migrations = MigrationHistory.objects.filter(app_name='south_test')

not_applied = list(set(all_migrations) - set([migration.get_migration() for migration in applied_migrations]))

现在你有了not_applied迁移。也许有一些幽灵迁移的细节。

详情见migrate南方司令部。

希望这可以帮助!

于 2013-06-26T00:48:09.437 回答
1

好的,我制作了一些中间件,可以满足我的需求。当您发出请求时,它会检查您尚未应用的迁移并引发异常。请务必仅在开发中使用此中间件!

您还可以在https://gist.github.com/gitaarik/5974176上找到源代码

from south import migration
from south.models import MigrationHistory


class SouthUnranMigrationCheck(object):

    def process_request(self, request):
        '''
        Checks if you ran all South migrations. If not, it will throw an
        exception (DidNotApplyAllMigrations).
        '''

        unapplied_migrations = self.unapplied_migrations()

        if len(unapplied_migrations) > 0:

            message = u'You haven\'t run the following migrations: {}'.format(
                u''.join(
                    [u'\n  "{}" in app "{}".'.format(name, app)
                    for name, app in unapplied_migrations]
                )
            )

            raise DidNotApplyAllMigrations(message)

    def unapplied_migrations(self):
        '''
        Returns a list of tuples of unapplied migrations. The tuples consist of
        a migration name and an app label.
        '''

        applied_migrations = self.applied_migrations()
        unapplied_migrations = []

        for app_migration_files in migration.all_migrations():

            for migration_file in app_migration_files:

                app_label = migration_file.app_label()
                migration_name = migration_file.name()

                if migration_name not in applied_migrations[app_label]:
                    unapplied_migrations.append((migration_name, app_label))

        return unapplied_migrations

    def applied_migrations(self):
        '''
        Returns a dictionary with the app name in the key, and a list of
        migrations in the value.
        '''

        applied_migrations = {}

        for applied_migration in MigrationHistory.objects.all():

            if applied_migration.app_name not in applied_migrations:
                applied_migrations[applied_migration.app_name] = []

            applied_migrations[applied_migration.app_name].append(
                applied_migration.migration)

        return applied_migrations


class DidNotApplyAllMigrations(Exception):
    '''
    Exception that indicates that you havent run all migrations.
    '''
    pass
于 2013-06-26T16:43:19.400 回答