Table 不存在测试只读 table (Django)
Table does not exist on testing a read-only table (Django)
我有一个 Django
项目。这个项目中有 2 个数据库,我写了一个 Router
来使其中一个 readonly
。我已经编写了一些使用此 readonly
数据库的单元测试,但是当我 运行 python manage.py test
它说
ProgrammingError: (1146, "Table 'test_arzesh-db.company' doesn't
exist")
这里是数据库的设置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'broker-website',
'USER': 'root',
'PASSWORD': '',
'HOST': 'localhost',
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
},
},
'arzesh-db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'arzesh-db',
'USER': 'root',
'PASSWORD': '',
'TEST_DATABASE': 'default',
},
'TEST': {
'CHARSET': 'utf8',
'COALATION': 'utf8-unicode-ci',
}
}
这是我的路由器代码:
class Router(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.app_label == 'arzesh':
return 'arzesh-db'
return 'default'
def db_for_write(self, model, **hints):
"""
Attempts to write auth models go to auth_db.
"""
if model._meta.app_label == 'arzesh':
return 'arzesh-db'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth app is involved.
"""
return True
def allow_migrate(self, db, app_label, model=None, **hints):
"""
Make sure the auth app only appears in the 'auth_db'
database.
"""
if app_label == 'arzesh':
return False
return True
这是只读数据库中的模型:
class Company(models.Model):
def __unicode__(self):
return self.tick
id = models.AutoField(primary_key=True)
tick = models.CharField(unique=True, max_length=32)
name = models.CharField(max_length=128, unique=True)
class Meta:
managed = False
db_table = 'company'
这是单元测试中出现错误的行:
company.objects.create(id=1, tick='a', name='a')
首先,这样说是不准确的,
I've written some unit tests that use this readonly database
那是因为
Tests that require a database (namely, model tests) will not use your
“real” (production) database. Separate, blank databases are created
for the tests.
...
The default test database names are created by prepending test_ to the
value of each NAME in DATABASES
参考:https://docs.djangoproject.com/en/1.9/topics/testing/overview/#the-test-database
这一点得到了证实,错误是
ProgrammingError: (1146, "Table 'test_arzesh-db.company' doesn't exist")
对了,那么测试数据库是如何创建的呢?根据您的迁移内容。但是你有
class Meta:
managed = False
db_table = 'company'
这里的managed = False
表示不会创建迁移,所以table不会存在于你的测试数据库中。因此错误。
解决方案。
使用 运行SQL 手动添加创建此 table 的迁移。为此使用 SHOW CREATE TABLE company
中的 SQL。首先做
./manage.py makemigrations myapp --empty
并编辑新创建的迁移文件以添加 运行Python 或 RunSQL code into it. The SQL that you pass into RunSQL is the SQL you generated by SHOW CREATE TBABLE company
in your mysql console. Please refer RunSQL 文档以获取更多信息和示例。
我有一个 Django
项目。这个项目中有 2 个数据库,我写了一个 Router
来使其中一个 readonly
。我已经编写了一些使用此 readonly
数据库的单元测试,但是当我 运行 python manage.py test
它说
ProgrammingError: (1146, "Table 'test_arzesh-db.company' doesn't exist")
这里是数据库的设置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'broker-website',
'USER': 'root',
'PASSWORD': '',
'HOST': 'localhost',
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
},
},
'arzesh-db': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'arzesh-db',
'USER': 'root',
'PASSWORD': '',
'TEST_DATABASE': 'default',
},
'TEST': {
'CHARSET': 'utf8',
'COALATION': 'utf8-unicode-ci',
}
}
这是我的路由器代码:
class Router(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.app_label == 'arzesh':
return 'arzesh-db'
return 'default'
def db_for_write(self, model, **hints):
"""
Attempts to write auth models go to auth_db.
"""
if model._meta.app_label == 'arzesh':
return 'arzesh-db'
return 'default'
def allow_relation(self, obj1, obj2, **hints):
"""
Allow relations if a model in the auth app is involved.
"""
return True
def allow_migrate(self, db, app_label, model=None, **hints):
"""
Make sure the auth app only appears in the 'auth_db'
database.
"""
if app_label == 'arzesh':
return False
return True
这是只读数据库中的模型:
class Company(models.Model):
def __unicode__(self):
return self.tick
id = models.AutoField(primary_key=True)
tick = models.CharField(unique=True, max_length=32)
name = models.CharField(max_length=128, unique=True)
class Meta:
managed = False
db_table = 'company'
这是单元测试中出现错误的行:
company.objects.create(id=1, tick='a', name='a')
首先,这样说是不准确的,
I've written some unit tests that use this readonly database
那是因为
Tests that require a database (namely, model tests) will not use your “real” (production) database. Separate, blank databases are created for the tests. ... The default test database names are created by prepending test_ to the value of each NAME in DATABASES
参考:https://docs.djangoproject.com/en/1.9/topics/testing/overview/#the-test-database
这一点得到了证实,错误是
ProgrammingError: (1146, "Table 'test_arzesh-db.company' doesn't exist")
对了,那么测试数据库是如何创建的呢?根据您的迁移内容。但是你有
class Meta:
managed = False
db_table = 'company'
这里的managed = False
表示不会创建迁移,所以table不会存在于你的测试数据库中。因此错误。
解决方案。
使用 运行SQL 手动添加创建此 table 的迁移。为此使用 SHOW CREATE TABLE company
中的 SQL。首先做
./manage.py makemigrations myapp --empty
并编辑新创建的迁移文件以添加 运行Python 或 RunSQL code into it. The SQL that you pass into RunSQL is the SQL you generated by SHOW CREATE TBABLE company
in your mysql console. Please refer RunSQL 文档以获取更多信息和示例。