在第二个数据库上运行 Python 迁移
RunPython migration on second database
运行 在第二个数据库上使用 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(...)
schema_editor.connection.alias
包含开始迁移的当前数据库的字符串。
因此每个 RunPython 迁移都必须使用此别名手动 select 正确的数据库。
示例:
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(...)
可用于 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),
]
运行 在第二个数据库上使用 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(...)
schema_editor.connection.alias
包含开始迁移的当前数据库的字符串。
因此每个 RunPython 迁移都必须使用此别名手动 select 正确的数据库。
示例:
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(...)
可用于 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),
]