我有一个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
选项就可以运行的方法
我有一个django项目,其中包含2个应用程序,每个应用程序都在不同的DB上运行(我们称它们为default和DB2)。我创建了一个路由器来管理数据,并将该路由器添加到我的settings.py中... ... >>
默认情况下,如果未提供,则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。>