我有一个django项目,其中包含2个应用程序,每个应用程序都在不同的DB上运行(我们称它们为default和DB2)。
我已经创建了一个路由器来管理数据,并将该路由器添加到我的settings.py
运行迁移时,我得到Applying analytics.0001_initial... OK
,但是在默认数据库中,唯一要更新的是django_migrations
表,该表显示应用程序分析已使用0001进行了迁移,而在DB2中,该表甚至根本没有创建。
转到Django shell并尝试做obj.objects.all()
给我表DB2.table_name不存在
我还验证了sql DB2中存在的内容,但没有我创建的表
我的路由器:
class DB2Router(object):
"""
A router for apps that connect directly to the DB2 database.
This router allows apps to directly update the DB2 database rather
than using raw SQL as in the past. The router forces the use of the DB2
database for any app in the "apps" list.
"""
db = "DB2"
apps = ["analytics"]
def db_for_read(self, model, **hints):
if model._meta.app_label in self.apps:
return self.db
return None
def db_for_write(self, model, **hints):
if model._meta.app_label in self.apps:
return self.db
return None
def allow_relation(self, obj1, obj2, **hints):
# Allow any relation between two models that are both in the same app.
if (obj1._meta.app_label in self.apps) and (obj2._meta.app_label in self.apps):
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label in self.apps:
return db == self.db
return None
我的模型:
class PartnerImpression(models.Model):
""" used to track impressions on widgets through our partners """
partner = models.CharField(max_length=1024)
referer = models.CharField(default="N/A", max_length=2048)
created = models.DateTimeField(auto_now_add=True, blank=True)
迁移:
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='PartnerImpression',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('partner', models.CharField(max_length=1024)),
('referer', models.CharField(default='N/A', max_length=2048)),
('created', models.DateTimeField(auto_now_add=True)),
],
),
]
DB2存在并且有一个空的django_migrations
表。
在manage.py migrate --database=DB2
命令中定义数据库不是一种选择,因为我在数十台服务器上运行了CI进程,并且无法在所有服务器上手动运行此进程,因此该命令需要保留无参数
我在迁移中不需要任何原始SQL
我也发现了这一点:Django migrations with multiple databases,但我不知道自2016年以来是否发生了任何变化,并且希望找到一种无需使用database
选项就可以运行的方法
答案 0 :(得分:1)
默认情况下,migrate
将--database
的值设为default
(DEFAULT_DB_ALIAS
)(如果未提供);因此,将对该数据库应用所有迁移。如果要使用Django提供的即用型功能,则必须使用--database
提及要操作的数据库。如果由于某种原因您不能使用它(如您提到的那样),则可以创建一个自定义管理命令,例如migrate_all
一次将所有迁移应用于所有数据库。
下面的示例方法仅显示了handle
方法的外观,您可以从migrate
中汲取灵感:
migrate_all.py
:
from importlib import import_module
from django.apps import apps
from django.db import connections
class Command(BaseCommand):
help = "Updates all database schemas."
def add_arguments(self, parser):
# Add arguments if you want
pass
def handle(self, *args, **options):
# Import the 'management' module within each installed app, to register
# dispatcher events.
for app_config in apps.get_app_configs():
if module_has_submodule(app_config.module, "management"):
import_module('.management', app_config.name)
# Iterate over and operate on each of the databases
for connection in connections.databases:
# https://github.com/django/django/blob/master/django/core/management/commands/migrate.py#L84
connection.prepare_database()
...
...
从connections.databases
,follow the operations from migrations
for each获得每个连接后。