我是Django的新手。 我在项目中创建了两个应用程序:
python3 manage.py startapp app1
python3 manage.py startapp app1
我使用Mysql作为数据库,我希望每个应用程序都应该使用不同的模式。
我尝试按照此处描述的步骤操作: Sharing (mysql) database between apps Django with Database routers
所以在 settings.py 中我定义了2个MySql模式并保留默认模式和 添加添加DATABASE_ROUTERS。
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'),
},
'mydb1':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'APP1DB',
'USER': 'user1',
'PASSWORD': '****',
'HOST': 'localhost', # Or an IP Address that your DB is hosted on
'PORT': '3306',
},
'mydb2':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'APP2DB',
'USER': 'user1',
'PASSWORD': '****',
'HOST': 'localhost', # Or an IP Address that your DB is hosted on
'PORT': '3306',
},
}
DATABASE_ROUTERS = ['app1.dbRouter.App1DBRouter', 'app2.dbRouter.App2DBRouter']
其他档案: APP1 / models1.py
from django.db import models
# Create your models here.
class Model1(models.Model):
name = models.CharField(max_length=100)
APP2 / models2.py
from django.db import models
# Create your models here.
class Model2(models.Model):
name = models.CharField(max_length=100)
和文件: APP1 / dbRouter.py
class App1DBRouter(object):
def db_for_read(self,model, **hints):
if model._meta.app_label == 'app1':
return 'mydb1'
return None
def db_for_write(self,model, **hints):
if model._meta.app_label == 'app1':
return 'mydb1'
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 == 'mydb1':
if model._meta.app_label == 'app1':
return True
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 'mydb2'
return None
def db_for_write(self,model, **hints):
if model._meta.app_label == 'app2':
return 'mydb2'
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 == 'mydb2':
if model._meta.app_label == 'app2':
return True
elif model._meta.app_label == 'app2':
return False
return None
在此之后,我希望当我运行命令makemigrations和migrate时,我会在2个不同的模式中获得2个不同的表吗? 所以:
$ python3 manage.py makemigrations
Migrations for 'app1':
app1/migrations/0001_initial.py
- Create model Model1
Migrations for 'app2':
app2/migrations/0001_initial.py
- Create model Model2
$ python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, app1, app2, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
...
Applying sessions.0001_initial... OK
但是除了两个模式中的 django_migrations 之外,没有创建表格。
如果我使用命令:
$ python3 manage.py migrate --database=mydb1
然后在APP1DB中创建两个模型表。
mysql> SHOW TABLES;
+----------------------------+
| Tables_in_APP1DB |
+----------------------------+
| app1_model1 |
| app2_model2 |
| auth_group |
那么如何解决这个问题?
答案 0 :(得分:2)
根据the documentation数据库路由器可以实现方法allow_migrate(db, app_label, model_name=None, **hints)
以确定是否应该执行某个迁移。始终通过默认数据库路由器django.db.router
:
def allow_migrate(self, db, app_label, **hints):
for router in self.routers:
try:
method = router.allow_migrate
except AttributeError:
# If the router doesn't have a method, skip to the next one.
continue
[...]
return True
因为您的路由器没有定义这样的方法,所以它只是在方法结束时返回True
,因此将请求的迁移应用于指定的数据库。
您可以通过定义此方法来实现跨不同数据库的应用程序分离:
class App1DBRouter(object):
[...]
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'app1':
return db == 'mydb1'
return None
同样适用于app2
。