我创建了一个django项目,然后创建了两个应用程序app1和app2。我希望这两个应用程序共享一个mysql数据库('nameofDB'到mysql,'mydb'到django)。我在settings.py中将数据库添加到DATABASES,并为每个应用创建了一个dbrouter文件,并将每个路由器添加到DATABASE_ROUTERS。另外在settings.py中将每个应用添加到INSTALLED_APPS。
我的问题是当我尝试制作
时python manage.py syncdb --database=mydb
因为它不同步两个应用程序(仅限app1)。它说:
Creating tables ...
Creating table app1_model1
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
这是我的settings.py:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app1',
'app2',
)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'mydb':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'nameofDB',
'USER':'username',
'PASSWORD':'password',
}
}
DATABASE_ROUTERS = ['app1.dbRouter.App1DBRouter', 'app2.dbRouter.App2DBRouter']
这是我的模特:
APP1 / models.py:
class Model1(models.Model):
name = models.CharField(max_length=100)
APP2 / models.py:
class Model2(models.Model):
name = models.CharField(max_length=100)
以下是我的dbrouters
APP1 / dbRouter.py
class App1DBRouter(object):
def db_for_read(self,model, **hints):
if model._meta.app_label == 'app1':
return 'mydb'
return None
def db_for_write(self,model, **hints):
if model._meta.app_label == 'app1':
return 'mydb'
return None
def allow_relation(self,obj1, obj2, **hints):
if obj1._meta.app_label == 'app1' and \
obj2._meta.app_label == 'app1':
return True
return None
def allow_syncdb(self,db, model):
if db == 'mydb':
return model._meta.app_label == 'app1'
elif model._meta.app_label == 'app1':
return False
return None
APP2 / dbRouter.py
class App2DBRouter(object):
def db_for_read(self,model, **hints):
if model._meta.app_label == 'app2':
return 'mydb'
return None
def db_for_write(self,model, **hints):
if model._meta.app_label == 'app2':
return 'mydb'
return None
def allow_relation(self,obj1, obj2, **hints):
if obj1._meta.app_label == 'app2' and \
obj2._meta.app_label == 'app2':
return True
return None
def allow_syncdb(self,db, model):
if db == 'mydb':
return model._meta.app_label == 'app2'
elif model._meta.app_label == 'app2':
return False
return None
它出了什么问题?我该怎么办?提前致谢! :)
答案 0 :(得分:1)
也许之前创建了app2_model2,检查一下!
你可以这样做:
<强> settings.py 强>
DATABASE_APPS_MAPPING = {'app1': 'mydb', 'app2': 'mydb'}
DATABASE_ROUTERS = ['path.router.DatabaseAppsRouter']
<强> router.py 强>
from django.conf import settings
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 settings.DATABASE_APPS_MAPPING.has_key(model._meta.app_label):
return settings.DATABASE_APPS_MAPPING[model._meta.app_label]
return None
def db_for_write(self, model, **hints):
"""Point all write operations to the specific database."""
if settings.DATABASE_APPS_MAPPING.has_key(model._meta.app_label):
return settings.DATABASE_APPS_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 = settings.DATABASE_APPS_MAPPING.get(obj1._meta.app_label)
db_obj2 = settings.DATABASE_APPS_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 settings.DATABASE_APPS_MAPPING.values():
return settings.DATABASE_APPS_MAPPING.get(model._meta.app_label) == db
elif settings.DATABASE_APPS_MAPPING.has_key(model._meta.app_label):
return False
return None
答案 1 :(得分:1)
我同意丹尼尔罗斯曼的观点。当你有两个或多个使用同一个数据库的应用程序时,你可以使用一个路由器。通常每个非默认数据库可能有一个路由器吗?
但如果你真的需要两台路由器就是一个解决方案。
只要allow_syncdb返回None,Django根数据库路由器就会尝试从DATABASE_ROUTERS开始的所有路由器。因此,App1DBRouter.allow_syncdb需要为model._meta.app_label =='app2'和db =='mydb'返回None(而不是False)。这样,App2DBRouter.allow_syncdb将有机会被调用。
我让你的syncdb处理以下更改
class App1DBRouter(object):
...
def allow_syncdb(self,db, model):
if db == 'mydb':
if model._meta.app_label == 'app1':
return True
elif model._meta.app_label == 'app1':
return False
return None
class App2DBRouter(object):
...
def allow_syncdb(self,db, model):
if db == 'mydb':
if model._meta.app_label == 'app2':
return True
else:
return False
elif model._meta.app_label == 'app2':
return False
return None