Django 1.6+のソリューションが存在します (1.11を含む) MySQL の場合 およびsqlite バックエンド、オプションForeignKey。 db_constraint =誤り
明示的なMeta.db_table
。データベース名とテーブル名が引用されている場合 '`'(MySQLの場合)または''"'(他のdbの場合)、例:db_table = '"db2"."table2"'
)。その後、それ以上引用されず、ドットは引用外になります。有効なクエリはDjangoORMによってコンパイルされます。より適切なソリューションは、db_table = 'db2"."table2'
です。 (これにより、結合が可能になるだけでなく、db制約の移行に近い1つの問題も発生します)
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では、他の必要な手順についてバックエンドで個別に話し合う必要があります。 同様の重要な質問 。
Djangoは参照整合性制約を作成できないため、オプション'db_constraint'が移行に必要です。ADD foreign key table1(fk_id) REFERENCES db2.table2(id)
、
ただし、手動で作成できます
MySQLの場合。
特定のバックエンドに関する質問は、実行時に別のデータベースをデフォルトに接続できるかどうか、およびデータベース間の外部キーがサポートされているかどうかです。これらのモデルも書き込み可能です。間接的に接続されたデータベースは、managed=False
のレガシーデータベースとして使用する必要があります (テーブルdjango_migrations
が1つしかないため 移行の追跡は、直接接続されたデータベースでのみ作成されます。このテーブルは、同じデータベース内のテーブルのみを記述している必要があります。)ただし、データベースシステムがそのようなインデックスをサポートしている場合、外部キーのインデックスは管理側で自動的に作成できます。
Sqlite3 :実行時に別のデフォルトのsqlite3データベースに接続する必要があります(answer SQLite-さまざまなデータベースのテーブルをどのように結合しますか )、せいぜいシグナル connection_created :
from django.db.backends.signals import connection_created
def 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") # optional
connection_created.connect(signal_handler)
もちろん、データベースルーターと通常のdjango...ForeignKey
は必要ありません。 db_constraint=Falseで使用できます。利点は、テーブル名がデータベース間で一意である場合、「db_table」が不要なことです。
MySQL 異なるデータベース間の外部キー 簡単です。 SELECT、INSERT、DELETEなどのすべてのコマンドは、データベース名を事前に添付せずにサポートします。
この質問は、レガシーデータベースに関するものでした。ただし、移行でも興味深い結果が得られました。