partir modelos inspectdb existente datos crear python django unit-testing

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.



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)