Một giải pháp tồn tại cho Django 1.6+ (bao gồm 1.11) cho MySQL và sqlite phụ trợ, theo tùy chọn ForeignKey. db_constraint =Sai
và Meta.db_table
rõ ràng . Nếu tên cơ sở dữ liệu và tên bảng được trích dẫn bởi '' '(đối với MySQL) hoặc bởi' "'(đối với db khác), ví dụ:db_table = '"db2"."table2"'
). Sau đó, nó không được trích dẫn nhiều hơn và dấu chấm là hết trích dẫn. Các truy vấn hợp lệ được biên dịch bởi Django ORM. Một giải pháp tương tự tốt hơn là db_table = 'db2"."table2'
(điều đó không chỉ cho phép tham gia mà còn bởi một vấn đề gần hơn là di chuyển ràng buộc chéo db)
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
Bộ truy vấn:
>>> 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'
Việc phân tích cú pháp truy vấn đó được hỗ trợ bởi tất cả các phần mềm phụ trợ db trong Django, tuy nhiên các bước cần thiết khác phải được thảo luận riêng bởi các phụ trợ. Tôi đang cố gắng trả lời một cách tổng quát hơn vì tôi đã tìm thấy câu hỏi quan trọng tương tự .
Tùy chọn 'db_constraint' là cần thiết cho việc di chuyển, vì Django không thể tạo ràng buộc toàn vẹn tham chiếu
ADD foreign key table1(fk_id) REFERENCES db2.table2(id)
,
nhưng có thể tạo thủ công
cho MySQL.
Một câu hỏi dành cho các phần mềm phụ trợ cụ thể là liệu cơ sở dữ liệu khác có thể được kết nối với cơ sở dữ liệu mặc định tại thời điểm chạy và khóa ngoại cơ sở dữ liệu chéo có được hỗ trợ hay không. Các mô hình này cũng có thể ghi được. Cơ sở dữ liệu được kết nối gián tiếp nên được sử dụng làm cơ sở dữ liệu kế thừa với managed=False
(vì chỉ một bảng django_migrations
để theo dõi di chuyển chỉ được tạo trong cơ sở dữ liệu được kết nối trực tiếp. Bảng này chỉ nên mô tả các bảng trong cùng một cơ sở dữ liệu.) Tuy nhiên, chỉ mục cho khóa ngoại có thể được tạo tự động ở phía được quản lý nếu hệ thống cơ sở dữ liệu hỗ trợ các chỉ mục đó.
Sqlite3 :Nó phải được đính kèm với cơ sở dữ liệu sqlite3 mặc định khác tại thời điểm chạy (answer SQLite - Làm cách nào để bạn nối các bảng từ các cơ sở dữ liệu khác nhau ). :
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)
Tất nhiên, nó không cần bộ định tuyến cơ sở dữ liệu và django...ForeignKey
bình thường có thể được sử dụng với db_constraint =False. Một ưu điểm là "db_table" không cần thiết nếu tên bảng là duy nhất giữa các cơ sở dữ liệu.
Trong MySQL khóa ngoại giữa các cơ sở dữ liệu khác nhau rất dễ dàng. Tất cả các lệnh như SELECT, INSERT, DELETE đều hỗ trợ bất kỳ tên cơ sở dữ liệu nào mà không cần đính kèm chúng trước đó.
Câu hỏi này là về cơ sở dữ liệu kế thừa. Tuy nhiên, tôi cũng có một số kết quả thú vị với việc di chuyển.