Mysql
 sql >> база данни >  >> RDS >> Mysql

Django ManyToMany с множество бази данни

Съществува решение за Django 1.6+ (включително 1.11) за MySQL и sqlite backends, чрез опция ForeignKey. db_constraint =False и изрично Meta.db_table . Ако името на базата данни и името на таблицата са в кавички от ' ' (за MySQL) или от ' " ' (за други db), напр. db_table = '"db2"."table2"' ). Тогава не се цитира повече и точката е извън цитирането. Валидни заявки се компилират от Django ORM. По-добро подобно решение е db_table = 'db2"."table2' (което позволява не само присъединяване, но и с един проблем е по-близо до преминаване на миграция на ограничение на 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

Набор от заявки:

>>> 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'

Този анализ на заявка се поддържа от всички сървъри на db в 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_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 поддържат всякакви имена на база данни, без да ги прикачват преди това.

Този въпрос беше за наследени бази данни. Имам обаче някои интересни резултати и с миграциите.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. „Харесвам („%this%“ ИЛИ „%that%“) и нещо=друго не работи

  2. 3 начина да откриете дали низ съответства на регулярен израз в MySQL

  3. SQL заявка връща false в PHP

  4. Разрешеният размер на паметта от 134217728 байта е изчерпан (опит за разпределяне на 42 байта)

  5. Тестове за приемане на Codeception в транзакция на база данни на MySQL