Django 数据库路由器
Django DB Routers
我的 Django 应用程序将为 3 个不同的应用程序(产品、制造商、基金)连接 3 个不同的数据库(默认为 SQLite,用于产品和制造商数据库的 PostgreSQL,用于基金数据库的 MSSQL)
我在每个应用程序的 routers.py
(productdbrouter
, manufacturerdbrouter
, fundsdbrouter
) 文件中创建了 3 个路由器,以根据 app_lable名字。
在我的项目设置文件中,我创建了一个 DATABASE_ROUTERS
配置为:
DATABASE_ROUTERS = [
"product.routers.productdbrouter","manufacturer.routers.manufacturerdbrouter", "funds.routers.fundsdbrouter",
]
现在,当我尝试访问应用程序时,它总是尝试从数据库配置中的第一个路由器中找到 table(在本例中为 product.routers.productdbrouter
),如果 table丢失然后它尝试从默认路由器(SQLite)获取。
我期望路由器根据我尝试获取的模型映射到 products/manufacturer/Funds 数据库。
非常感谢关于我在配置上缺少什么的建议?
顺便说一下,我使用的是 Django=2.2.4
代码
products\router.py
class productdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'product':
return 'productdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'product' and obj2._meta.app_label == 'product':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='product':
return db=='productdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'productdb' or model._meta.app_label == "product":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
manufacturer\router.py
class manufacturerdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'manufacturer':
return 'manufacturerdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'manufacturer' and obj2._meta.app_label == 'manufacturer':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='manufacturer':
return db=='manufacturerdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'manufacturerdb' or model._meta.app_label == "manufacturer":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
funds\router.py
class fundsdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'funds':
return 'fundsdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'funds':
return 'fundsdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'funds' and obj2._meta.app_label == 'funds':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='funds':
return db=='fundsdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'fundsdb' or model._meta.app_label == "funds":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
注意:我设置了 allow_syncdb =false,因为我没有从 django 应用程序中推送任何值。在应用程序中所做的所有更改将通过其他应用程序进行。
感谢帮助
我认为问题在于您使用代码 return 'default'
而不是使用 return None
返回建议。请参阅此处的文档:
https://docs.djangoproject.com/en/2.2/topics/db/multi-db/#database-routers
您也可以在整个项目中使用单个路由器,就像这样:
class MyRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
elif model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
elif model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return None
def allow_relation(self, obj1, obj2, **hints):
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db in (
'productdb',
'manufacturerdb',
):
return False
return True
我们正在做的是将您创建的每个 Django 应用程序的读写路由到适当的数据库(如 Django 设置中 DATABASES
中所定义),或返回 None
,这将在您的设置中使用默认的 SQLite 数据库。我们还告诉 Django 不要创建任何针对 PostgreSQL 或 MSSQL 的迁移,因为我猜你不会想让 Django 处理这些数据库的结构。
不过,我们这里不考虑allow_relation
;是否设置任何跨数据库边界的关系取决于您。例如,您无法设置从 SQLite 到 PostgreSQL 的 ForeignKey
。祝你好运!
我的 Django 应用程序将为 3 个不同的应用程序(产品、制造商、基金)连接 3 个不同的数据库(默认为 SQLite,用于产品和制造商数据库的 PostgreSQL,用于基金数据库的 MSSQL)
我在每个应用程序的 routers.py
(productdbrouter
, manufacturerdbrouter
, fundsdbrouter
) 文件中创建了 3 个路由器,以根据 app_lable名字。
在我的项目设置文件中,我创建了一个 DATABASE_ROUTERS
配置为:
DATABASE_ROUTERS = [
"product.routers.productdbrouter","manufacturer.routers.manufacturerdbrouter", "funds.routers.fundsdbrouter",
]
现在,当我尝试访问应用程序时,它总是尝试从数据库配置中的第一个路由器中找到 table(在本例中为 product.routers.productdbrouter
),如果 table丢失然后它尝试从默认路由器(SQLite)获取。
我期望路由器根据我尝试获取的模型映射到 products/manufacturer/Funds 数据库。
非常感谢关于我在配置上缺少什么的建议?
顺便说一下,我使用的是 Django=2.2.4
代码
products\router.py
class productdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'product':
return 'productdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'product' and obj2._meta.app_label == 'product':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='product':
return db=='productdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'productdb' or model._meta.app_label == "product":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
manufacturer\router.py
class manufacturerdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'manufacturer':
return 'manufacturerdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'manufacturer' and obj2._meta.app_label == 'manufacturer':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='manufacturer':
return db=='manufacturerdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'manufacturerdb' or model._meta.app_label == "manufacturer":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
funds\router.py
class fundsdbrouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label== 'funds':
return 'fundsdb'
return 'default'
def db_for_write(self, model, **hints):
if model._meta.app_label == 'funds':
return 'fundsdb'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
if obj1._meta.app_label == 'funds' and obj2._meta.app_label == 'funds':
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label=='funds':
return db=='fundsdb'
return 'default'
def allow_syncdb(self, db, model):
if db == 'fundsdb' or model._meta.app_label == "funds":
return False # we're not using syncdb on our legacy database
else: # but all other models/databases are fine
return True
注意:我设置了 allow_syncdb =false,因为我没有从 django 应用程序中推送任何值。在应用程序中所做的所有更改将通过其他应用程序进行。
感谢帮助
我认为问题在于您使用代码 return 'default'
而不是使用 return None
返回建议。请参阅此处的文档:
https://docs.djangoproject.com/en/2.2/topics/db/multi-db/#database-routers
您也可以在整个项目中使用单个路由器,就像这样:
class MyRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
elif model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return None
def db_for_write(self, model, **hints):
if model._meta.app_label == 'product':
return 'productdb'
elif model._meta.app_label == 'manufacturer':
return 'manufacturerdb'
return None
def allow_relation(self, obj1, obj2, **hints):
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
if db in (
'productdb',
'manufacturerdb',
):
return False
return True
我们正在做的是将您创建的每个 Django 应用程序的读写路由到适当的数据库(如 Django 设置中 DATABASES
中所定义),或返回 None
,这将在您的设置中使用默认的 SQLite 数据库。我们还告诉 Django 不要创建任何针对 PostgreSQL 或 MSSQL 的迁移,因为我猜你不会想让 Django 处理这些数据库的结构。
不过,我们这里不考虑allow_relation
;是否设置任何跨数据库边界的关系取决于您。例如,您无法设置从 SQLite 到 PostgreSQL 的 ForeignKey
。祝你好运!