在第二个数据库上运行RunPython

时间:2016-04-20 11:59:52

标签: django django-migrations

在第二个数据库上使用RunPython运行数据库迁移失败

python3 manage.py migrate --database=app

问题是apps.get_model方法采用已经进行了最新迁移的默认数据库。

不起作用:

def copy_cpr_cents_to_euros(apps, schema_editor):
    User = apps.get_model('accounting', 'User')
    User.objects.filter(...);

使用:

def copy_cpr_cents_to_euros(apps, schema_editor):
    User = apps.get_model('accounting', 'User')
    User.objects.using('app').filter(...);

有没有办法在迁移中使用给定的数据库,所以在这种情况下“app”没有明确地声明它,因为它应该适用于两个数据库?

类似于:

User.objects.using(database_name).filter(...)

2 个答案:

答案 0 :(得分:1)

schema_editor.connection.alias

包含用于启动迁移的当前数据库的字符串。

因此,每个RunPython迁移必须使用此别名手动选择正确的数据库。

示例:

def copy_cpr_cents_to_euros(apps, schema_editor):
    User = apps.get_model('accounting', 'User')
    db = schema_editor.connection.alias
    User.objects.using('app').using(db).filter(...)

答案 1 :(得分:0)

可用于 RunPython 函数的装饰器,以指定它应该针对哪个 DB 执行 [在 Django 1.8 上测试]

def only_default_db_migration(func):
    return only_databases_migration('default')(func)


def only_databases_migration(*db_aliases):
    """Restrict running Data Migrations on wanted databases only"""
    def decorate(func):
        def run_python_func(apps, schema_editor):
            db_alias = schema_editor.connection.alias
            if db_alias in db_aliases:
                return func(apps, schema_editor)
            else:
                print(f'Skip RunPython {func.__name__!r} for db with alias {db_alias!r}')
        return run_python_func
    return decorate

only_default_db_migration 的使用


@only_default_db_migration
def migrate_spam_check_processed_at(apps, schema_editor):
    apps.get_model("queues","Queue").objects.all().update(check=F('created'))


class Migration(migrations.Migration):

    operations = [
        migrations.RunPython(migrate_spam_check_processed_at),
    ]