Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

एक और स्कीमा में Django विदेशी कुंजी

मुझे आपके मामले का अनुकरण करने के लिए दो डेटाबेस का उपयोग करने की कोशिश की गई है, और नीचे समाधान खोजने की कोशिश की गई है:

<एच3>1. परिदृश्य:
  1. डेटाबेस schema1 , जिसे django द्वारा प्रबंधित किया जाता है (पढ़ें और लिखें)
  2. डेटाबेस schema2 , जो नहीं है django द्वारा प्रबंधित
<एच3>2. कदम:
  1. माइग्रेशन बनाएं python manage.py makemigrations आपके मॉडल के लिए
  2. अपने माइग्रेशन के लिए SQL जेनरेट करें:python manage.py sqlmigrate app 0001 .(मान लें कि जेनरेट की गई माइग्रेशन फ़ाइल का नाम 0001_initial.py है चरण 1 से )

इस माइग्रेशन के लिए sql इस तरह दिखना चाहिए:

CREATE TABLE `user_info` (`id_id` integer NOT NULL PRIMARY KEY, `name` varchar(20) NOT NULL);
ALTER TABLE `user_info` ADD CONSTRAINT `user_info_id_id_e8dc4652_fk_schema2.user_extra_info_id` FOREIGN KEY (`id_id`) REFERENCES `user_extra_info` (`id`);
COMMIT;

यदि आप उपरोक्त sql को सीधे चलाते हैं, तो आप इस तरह की त्रुटि के साथ समाप्त हो जाएंगे:

django.db.utils.OperationalError: (1824, "Failed to open the referenced table 'user_extra_info'")

ऐसा इसलिए है क्योंकि django मानता है कि आपके सभी माइग्रेशन चरण एक ही डेटाबेस में निष्पादित होते हैं . इसलिए यह user_extra_info का पता नहीं लगा सकता है schema1 . में डेटाबेस।

<एच3>3. निम्नलिखित चरण:
  1. स्पष्ट रूप से डेटाबेस निर्दिष्ट करें schema2 तालिका के लिए user_extra_info :

    ALTER TABLE `user_info` ADD CONSTRAINT `user_info_id_id_e8dc4652_fk_schema2.user_extra_info_id` FOREIGN KEY (`id_id`) REFERENCES schema2.user_extra_info (`id`);
    
  2. मैन्युअल रूप से संशोधित sql को schema1 . में चलाएँ डेटाबेस।

  3. django को बताएं कि मैंने खुद माइग्रेशन चलाया है:python manage.py migrate --fake

  4. हो गया !!

स्रोत कोड आपके संदर्भ के लिए:

models.py

from django.db import models


class UserExtraInfo(models.Model):
    # table in schema2, not managed by django
    name = models.CharField('name', max_length=20)

    class Meta:
        managed = False
        db_table = 'user_extra_info'


class UserInfo(models.Model):
    # table in schema1, managed by django
    id = models.OneToOneField(
        UserExtraInfo,
        on_delete=models.CASCADE,
        primary_key=True
    )
    name = models.CharField('user name', max_length=20)

    class Meta:
        db_table = 'user_info'

settings.py

# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'schema1',
        'USER': 'USER',
        'PASSWORD': 'PASSWORD',
        'HOST': 'localhost',
        'PORT': 3306,
    },
    'extra': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'schema2',
        'USER': 'USER',
        'PASSWORD': 'PASSWORD',
        'HOST': 'localhost',
        'PORT': 3306,
    }
}

DATABASE_ROUTERS = ['two_schemas.router.DBRouter']

router.py

class DBRouter(object):
    """
    A router to control all database operations on models in the
    auth application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read auth models go to auth_db.
        """
        if model._meta.db_table == 'user_extra_info':
            # specify the db for `user_extra_info` table
            return 'extra'
        if model._meta.app_label == 'app':
            return 'default'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write auth models go to auth_db.
        """
        if model._meta.db_table == 'user_extra_info':
            # specify the db for `user_extra_info` table
            return 'extra'
        if model._meta.app_label == 'app':
            return 'default'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Relations between objects are allowed if both objects are
        in the primary/replica pool.
        """
        db_list = ('default', 'extra')
        if obj1._state.db in db_list and obj2._state.db in db_list:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the auth app only appears in the 'auth_db'
        database.
        """
        if app_label == 'app':
            return db == 'default'
        return None


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कोडइग्निटर:डेटाबेस में एक छवि संग्रहित करना?

  2. डेटाबेस में डुप्लिकेट स्ट्रिंग खोजें

  3. टाइमस्टैम्प द्वारा php mysql ऑर्डर गलत है

  4. मैं टर्मिनल से MySQL के साथ डेटाबेस कैसे आयात कर सकता हूं?

  5. MySQL इंजेक्शन - अद्यतन/हटाने के लिए चयन क्वेरी का उपयोग करें