首頁 > 軟體

Django專案設定連線多個資料庫的方法記錄

2022-05-18 16:01:28

一個APP對應一個預設資料庫,若連線其他資料庫用".using()"

Author.objects.using('db02').all()

1、在專案settings中增加資料庫設定

# settings.py
 
DATABASES = {
  'default': {
   'ENGINE': 'django.db.backends.oracle',
     'NAME': 'orcl19c', 
     'USER': "username01",
     'PASSWORD': "password01",
     'HOST': "110.10.1.11",
     'PORT': 1511,
 },
  'db_2': {
   'ENGINE': 'django.db.backends.oracle',
     'NAME': 'orcl19c', 
     'USER': "username02",
     'PASSWORD': "password02",
     'HOST': "120.20.2.22",
     'PORT': 1512,
 }
}
# 以下MyProject改成專案名,預設default不用修改
DATABASE_ROUTERS = ['MyProject.database_router.DatabaseAppsRouter']
DATABASE_APPS_MAPPING = {
    'app01': 'default',
    'app02': 'db_2',
}

2、在專案根目錄下Myproject/Myproject 新建資料庫路由檔案database_router.py

直接複製以下程式碼,無需修改

from django.conf import settings
 
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING

class DatabaseAppsRouter(object):
    """
    A router to control all database operations on models for different
    databases.
    In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
    will fallback to the `default` database.
    Settings example:
    DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
    """
    def db_for_read(self, model, **hints):
        """"Point all read operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None
 
    def db_for_write(self, model, **hints):
        """Point all write operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None
 
    def allow_relation(self, obj1, obj2, **hints):
        """Allow any relation between apps that use the same database."""
        db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
        db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
        return None
 
    def allow_syncdb(self, db, model):
        """Make sure that apps only appear in the related database."""
 
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(model._meta.app_label) == db
        elif model._meta.app_label in DATABASE_MAPPING:
            return False
        return None
 
    def allow_migrate(self, db, app_label, model=None, **hints):
        """
        Make sure the auth app only appears in the 'auth_db'
        database.
        """
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None

3、使用inspectdb反向生成各app的model類之後,設定model類對應要連結的資料庫

反向生成models.py 命令:

python manage.py inspectdb --database db1 TableName1 > app01/models.py
 
python manage.py inspectdb --database db2 TableName2 > app02/models.py
# 編輯app01下的models.py:
class Names(models.Model): #該model使用default資料庫
    id=models.CharField(primary_key=True,max_length=100, blank=True, null=True)
    name=models.CharField(max_length=32,primary_key=True,unique=True)
    
    class Meta:
        #app_label = 'app01' #由於該model連線default資料庫,所以在此無需指定
        db_table = 'names'
        
# 編輯app02下的models.py:
class Classnum(models.Model): #該model使用default資料庫
    id=models.CharField(primary_key=True,max_length=100, blank=True, null=True)
    classnum=models.CharField(max_length=32,primary_key=True,unique=True)
    
    class Meta:
        app_label = 'app02'
        db_table = 'classnum'

 4、同步資料庫

# 同步default節點資料庫,只執行不帶 --database引數的命令,不對其他資料庫進行同步
 
python manage.py makemigrations
 
python manage.py migrate
 
# 同步db02節點資料庫:
 
python manage.py makemigrations
 
python manage.py migrate --database=db02

5、若要連線設定外的資料庫

Author.objects.using('other').all()
my_object.save(using='legacy_users')
my_object.delete(using='legacy_users')

移動物件到另一個資料庫時會發生主鍵衝突,可以使用obj.pk方法清除主鍵再儲存物件 

>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.pk = None # Clear the primary key.
>>> p.save(using='second') # Write a 

總結

到此這篇關於Django專案設定連線多個資料庫的文章就介紹到這了,更多相關Django設定連線多資料庫內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com