通过选择ForeignKey,可以为
MySQL* 和 sqlite 后端提供针对 Django 1.6+
(包括1.11)的解决方案。
db_constraint
=
False和显式。如果数据库名和表名被
引用 的“’”(用于MySQL的)或者““”(对于其他数据库),例如),然后它不引用更多的点是引出来。有效的查询是通过编译Django
ORM。一种更好的类似解决方案是(不仅允许连接,而且还允许跨数据库约束迁移更近一个问题)
****
*meta.db_table
****
db_table = '"db2"."table2"'``db_table ='db2"."table2'
db2_name = settings.DATAbaseS['db2']['NAME']class Table1(models.Model): fk = models.ForeignKey('Table2', on_delete=models.DO_NOTHING, db_constraint=False)class Table2(models.Model): name = models.CharField(max_length=10) .... class meta: db_table = '`%s`.`table2`' % db2_name # for MySQL # db_table = '"db2"."table2"' # for all other backends managed = False查询集:
>>> qs = Table2.objects.all()>>> str(qs.query)'SELECT "DB2"."table2"."id" FROM DB2"."table2"'>>> qs = Table1.objects.filter(fk__name='B')>>> str(qs.query)SELECt "app_table1"."id" FROM "app_table1" INNER JOIN "db2"."app_table2" ON ( "app_table1"."fk_id" = "db2"."app_table2"."id" ) WHERe "db2"."app_table2"."b" = 'B'
Django中的 所有数据库后端 都支持该查询解析,但是 后端
必须单独讨论其他必要的步骤。我试图更笼统地回答,因为我发现了一个类似的重要问题。
对于迁移而言,选项’db_constraint’是必需的,因为Django无法创建参考完整性约束
ADD foreign key table1(fk_id) REFERENCES db2.table2(id),
但可以为MySQL手动创建。
有关特定后端的问题是,是否可以在运行时将另一个数据库连接到默认数据库,以及是否支持跨数据库外键。这些模型也是可写的。间接连接的数据库应与以下数据库一起用作旧数据库
managed=False(因为仅
django_migrations在直接连接的数据库中仅创建了一个用于迁移跟踪的表。该表应仅描述同一数据库中的表。)但是可以自动创建外键索引如果数据库系统支持此类索引,则在受管端。
Sqlite3 :它必须在运行时附加到另一个默认的sqlite3数据库(答案SQLite-
如何连接来自不同数据库的表),最多只能通过connection_created信号发出:
from django.db.backends.signals import connection_createddef signal_handler(sender, connection, **kwargs): if connection.alias == 'default' and connection.vendor == 'sqlite': cur = connection.cursor() cur.execute("attach '%s' as db2" % db2_name) # cur.execute("PRAGMA foreign_keys = ON") # optionalconnection_created.connect(signal_handler)然后,它当然不需要数据库路由器,并且
django...ForeignKey可以使用db_constraint =
False来使用普通模式。一个优点是,如果表名在数据库之间是唯一的,则不需要“ db_table”。
在 MySQL中 ,不同数据库之间的外键很容易。所有命令(例如SELECT,INSERT,DELETE)都支持任何数据库名称,而无需附加它们。
这个问题是关于遗留数据库的。但是,对于迁移,我也得到了一些有趣的结果。



