python - modelos - django base de datos existente
Cómo crear una tabla durante las pruebas de Django con managed=False (7)
Buena solución plug and play. Simplemente pegue esto antes de su definición de clase de prueba. (nota: django 1.8 usado)
from django.db.models.loading import get_models
def change_managed_settings_just_for_tests():
"""django model managed bit needs to be switched for tests."""
unmanaged_models = [m for m in get_models() if not m._meta.managed]
for m in unmanaged_models:
m._meta.managed = True
change_managed_settings_just_for_tests()
Tengo un modelo con gestionado = Falso.
class SampleModel(models.Model):
apple = models.CharField(max_length=30)
orange = models.CharField(max_length=30)
class Meta:
managed = False
Tengo una prueba unitaria que crea un modelo de muestra, sin embargo, cuando ejecuto la prueba obtengo:
DatabaseError: no such table: SAMPLE_SAMPLE_MODEL
Los documentos de django: https://docs.djangoproject.com/en/dev/ref/models/options/#managed documenta lo siguiente:
Para las pruebas que involucran modelos con managed = False, depende de usted asegurarse de que se creen las tablas correctas como parte de la configuración de la prueba.
¿Cómo puedo realmente "crear" las tablas durante la configuración de prueba? O, alternativamente, ¿cómo puedo hacerlo para que cuando esté ejecutando pruebas, este modelo se haya "administrado = Verdadero" durante toda la prueba?
En la aplicación real, este modelo está respaldado por una vista en la base de datos. Sin embargo, durante el transcurso de la prueba, me gustaría tratar esto como una tabla y poder insertar datos de prueba allí.
Crea tu propio corredor de prueba usando esto:
from django.test.simple import DjangoTestSuiteRunner
class NoDbTestRunner(DjangoTestSuiteRunner):
""" A test runner to test without database creation """
def setup_databases(self, **kwargs):
""" Override the database creation defined in parent class """
#set manage=True for that specific database on here
Luego, en su configuración, agregue esta clase a TEST_RUNNER.
Echa un vistazo a esta entrada del blog: http://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/ Describe en detalle la creación de un Corredor de prueba para modelos no gestionados.
Ejecute el SQL sin formato para crear la tabla en la configuración de prueba:
from django.db import connection
class MyTest(unittest.TestCase):
def setUp(self):
connection.cursor().execute("CREATE TABLE ...")
def tearDown(self):
connection.cursor().execute("DROP TABLE ...")
Puede usar SchemaEditor en el método TestCase.setUp
para crear explícitamente modelos con managed = False
.
# models.py
from django.db import models
class Unmanaged(models.Model):
foo = models.TextField()
class Meta:
# This model is not managed by Django
managed = False
db_table = ''unmanaged_table''
Y en tus pruebas:
# tests.py
from django.db import connection
from django.test import TestCase
from myapp.models import Unmanaged
class ModelsTestCase(TestCase):
def setUp(self):
super().setUp()
with connection.schema_editor() as schema_editor:
schema_editor.create_model(Unmanaged)
if Unmanaged._meta.db_table not in connection.introspection.table_names():
raise ValueError("Table `{table_name}` is missing in test database.".format(table_name=Unmanaged._meta.db_table))
def tearDown(self):
super().tearDown()
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(Unmanaged)
def test_unmanaged_model(self):
with self.assertNumQueries(num=3):
self.assertEqual(0, Unmanaged.objects.all().count())
Unmanaged.objects.create()
self.assertEqual(1, Unmanaged.objects.all().count())
Solo para agregar: django.db.models.loading.get_models se eliminará en Django 1.9 (consulte https://github.com/BertrandBordage/django-cachalot/issues/33 ).
A continuación se muestra una actualizada para Django 1.10:
class UnManagedModelTestRunner(DiscoverRunner):
''''''
Test runner that automatically makes all unmanaged models in your Django
project managed for the duration of the test run.
Many thanks to the Caktus Group
''''''
def setup_test_environment(self, *args, **kwargs):
from django.apps import apps
self.unmanaged_models = [m for m in apps.get_models() if not m._meta.managed]
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 unmanaged models
for m in self.unmanaged_models:
m._meta.managed = False
Tenga en cuenta que también debe cuidar las migraciones (consulte Prueba de la aplicación django con varias bases de datos heredadas )
MIGRATION_MODULES = {
''news'': ''news.test_migrations'',
''economist'': ''economist.test_migrations''
}
Una solución rápida si no tiene muchas tablas no administradas:
Primero agregue una nueva variable a la configuración.
# settings.py
import sys
UNDER_TEST = (len(sys.argv) > 1 and sys.argv[1] == ''test'')
luego en los modelos
# models.py
from django.conf import settings
class SampleModel(models.Model):
apple = models.CharField(max_length=30)
orange = models.CharField(max_length=30)
class Meta:
managed = getattr(settings, ''UNDER_TEST'', False)