多数据库和非托管模型-测试用例失败 [英] Multi db and unmanged models - Test case are failing
问题描述
我有使用非托管(只读)模型的mutlidb设置。这些模型没有任何迁移。我正在尝试测试view.py的功能。在sqlite3数据库中,测试表的这些架构未在导致测试用例失败的情况下引起问题。
在view.py中,我导入了非托管(只读)模型失败。
I have mutlidb setup with unmanaged (read-only) models. There's no migrations for these models. I was trying to test the functionality of the view.py. In sqlite3 database these schema of the test table is not creating a causing an issue in failing the test case. In the view.py I have imported the unamanaged (read-only) model is failing.
我点击了链接以进行测试针对非托管模型进行测试
I have followed the link for test Testing against unmanaged models
-db设置
from django.test.runner import DiscoverRunner
class DisableMigrations(object):
def __contains__(self, item):
return True
def __getitem__(self, item):
return None
class UnManagedModelTestRunner(DiscoverRunner):
def setup_test_environment(self, *args, **kwargs):
from django.apps import apps
# app_name = apps.get_app_config('core_esp')
self.unmanaged_models = [m for m in apps.get_models() if not m._meta.managed and m._meta.app_label is 'core_esp']
for m in self.unmanaged_models:
m._meta.managed = True
super(UnManagedModelTestRunner, self).setup_test_environment(*args, **kwargs)
def teardown_test_environment(self, *args, **kwargs):
super(UnManagedModelTestRunner, self).teardown_test_environment(*args, **kwargs)
# reset un managed models
for m in self.unmanaged_models:
m._meta.managed = False
settings.py
if 'test' in sys.argv or 'test_coverage' in sys.argv:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
},
'test_db': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
}
}
INSTALLED_APPS = ['test']
# Skip the migrations by setting "MIGRATION_MODULES"
# to the DisableMigrations class defined above
#
MIGRATION_MODULES = DisableMigrations()
# Set Django's test runner to the custom class defined above
TEST_RUNNER = 'apps.settings.test_runner.UnManagedModelTestRunner'
DATABASE_ROUTERS = ('apps.tests.test_dbrouter.TestApiRouter', )
< h1> models.py
from django.db import models
class TestModelA(models.Model):
testid = models.CharField(max_length=200)
class Meta:
managed = False
db_table = 'TestD'
class TestModelB(models.Model):
testid = models.CharField(max_length=200)
class Meta:
managed = False
db_table = 'test_model_b'
app_label = 'application_b'
test.py
class MyTestCase(TestCase):
def test_my_function(self):
# view is called
# serializer called with read only model
pass
错误
Traceback (most recent call last):
File "C:\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\lib\site-packages\django\db\backends\sqlite3\base.py", line 383, in execute return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such table: TestD
The above exception was the direct cause of the following exception: Traceback (most recent call last):
File "manage.py", line 21, in <module> main()
File "manage.py", line 17, in main execute_from_command_line(sys.argv)
File "C:\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line utility.execute()
File "C:\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\lib\site-packages\django\core\management\commands\test.py", line 23, in run_from_argv
super().run_from_argv(argv)
File "C:\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\lib\site-packages\django\core\management\base.py", line execute
output = self.handle(*args, **options)
File "C:\lib\site-packages\django\core\management\commands\test.py", line 53, in handle failures = test_runner.run_tests(test_labels)
File "C:\lib\site-packages\django\test\runner.py", line 627, in run_tests
suite = self.build_suite(test_labels, extra_tests)
File "C:\lib\site-packages\django\test\runner.py", line 488, in build_suites
tests = self.test_loader.loadTestsFromName(label)
File "c:\program files\python37\Lib\unittest\loader.py", line 154, in loadTestsFromName
module = __import__(module_name)
File "C:\tests\tests.py", line 5, in <module>
from .views import (
File "C:\views.py", line 6, in <module>
from .serializers import (
File "C:\serializers.py", line 9, in <module>
class TestSerializer(serializers.Serializer):
File "C:\serializers.py", line 13, in TestSerializer
required=False, style={'base_template': 'select_multiple.html'}
File "C:\lib\site-packages\rest_framework\fields.py", line 1476, in __init__
super(MultipleChoiceField, self).__init__(*args, **kwargs)
File "C:\lib\site-packages\rest_framework\fields.py", line 1417, in __init__
self.choices = choices
File "C:\lib\site-packages\rest_framework\fields.py", line 1453, in _set_choices
for row in compiler.results_iter(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size):
File "C:\lib\site-packages\django\db\models\sql\compiler.py", line 1052, in results_iter
results = self.execute_sql(MULTI, chunked_fetch=chunked_fetch, chunk_size=chunk_size)
File "C:\lib\site-packages\django\db\models\sql\compiler.py", line 1100, in execute_sql
cursor.execute(sql, params)
File "C:\lib\site-packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False,
executor=self._execute)
File "C:\lib\site-packages\django\db\backends\utils.py", line 76, in
_execute_with_wrappers
return executor(sql, params, many, context)
File "C:\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\lib\site-packages\django\db\backends\sqlite3\base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: TESTD
推荐答案
我可以向您展示如何解决此问题;
I can show you how I am solving this issue;
所以我创建了一个信号,或多或少看起来像这样:
So I've created a signal, which more or less looks like this:
def create_test_models(**kwargs):
if "test" in sys.argv:
Organization = apps.get_model("organizations.Organization")
... # other models here too
# as we do not manage it - we need to create it manually;
with connection.schema_editor() as schema_editor:
sid = transaction.savepoint()
try:
schema_editor.create_model(Organization)
... # different models here if needed
transaction.savepoint_commit(sid)
except ProgrammingError: # tables already exists;
transaction.savepoint_rollback(sid)
此信号在配置中以<$ c连接$ c> pre_migrate 信号:
This signal is connected in the config as pre_migrate
signal:
class OrganizationsConfig(AppConfig):
name = "engine.organizations"
def ready(self):
# run after each migration; so each deploy, but this method can handle the
# incremental updates.
pre_migrate.connect(create_test_models, sender=self)
这也许不是超级解决方案-但是它可以正常工作,并且您已经在测试期间创建了模型,您可以使用它们或创建测试数据等。
It is maybe not super solution - but it is working and you have models created during tests and you can play with them or create test data etc.
希望这将有助于您前进。
Hope that this will help you to move forward.
这篇关于多数据库和非托管模型-测试用例失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!