[Python] Running Django tests ends with MigrationSchemaMissing exception

Discussão em 'Python' iniciado por Stack, Abril 10, 2025.

  1. Stack

    Stack Membro Participativo

    I'm writing because I have a big problem. Well, I have a project in Django where I am using django-tenants. Unfortunately, I can't run any tests as these end up with the following error when calling migrations: ‘django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table (no schema has been selected to create in LINE 1: CREATE TABLE ‘django_migrations’ (‘id’ bigint NOT NULL PRIMA...’

    The problem is quite acute. I am fed up with regression errors and would like to write tests for the code. I will appreciate any suggestion. If you have any suggestions for improvements to the project, I'd love to read about that too.

    Project details below. Best regards

    Dependencies

    [tool.poetry.dependencies]
    python = "^3.13"
    django = "5.1.8" # The newest version is not compatible with django-tenants yet
    django-tenants = "^3.7.0"
    dj-database-url = "^2.3.0"
    django-bootstrap5 = "^25.1"
    django-bootstrap-icons = "^0.9.0"
    uvicorn = "^0.34.0"
    uvicorn-worker = "^0.3.0"
    gunicorn = "^23.0.0"
    whitenoise = "^6.8.2"
    encrypt-decrypt-fields = "^1.3.6"
    django-bootstrap-modal-forms = "^3.0.5"
    django-model-utils = "^5.0.0"
    werkzeug = "^3.1.3"
    tzdata = "^2025.2"
    pytz = "^2025.2"
    psycopg = {extras = ["binary", "pool"], version = "^3.2.4"}
    django-colorfield = "^0.13.0"
    sentry-sdk = {extras = ["django"], version = "^2.25.1"}


    Settings.py

    import os
    from pathlib import Path
    from uuid import uuid4

    # External Dependencies
    import dj_database_url
    from django.contrib.messages import constants as messages
    from django.utils.translation import gettext_lazy as _

    BASE_DIR = Path(__file__).resolve().parent.parent
    PROJECT_DIR = os.path.join(BASE_DIR, os.pardir)
    TENANT_APPS_DIR = BASE_DIR / "tenant"

    DEBUG = os.environ.get("DEBUG", "False").lower() in ["true", "1", "yes"]
    TEMPLATE_DEBUG = DEBUG
    SECRET_KEY = os.environ.get("SECRET_KEY", str(uuid4())) if DEBUG else os.environ["SECRET_KEY"]
    VERSION = os.environ.get("VERSION", "develop")
    SECURE_SSL_REDIRECT = os.environ.get("SECURE_SSL_REDIRECT", "False").lower() in ["true", "1", "yes"]

    try:
    ALLOWED_HOSTS = os.environ["ALLOWED_HOSTS"].split(";")
    except KeyError:
    if not DEBUG:
    raise

    ALLOWED_HOSTS = ["localhost", ".localhost"]

    DEFAULT_DOMAIN = os.environ.get("DEFAULT_DOMAIN", ALLOWED_HOSTS[0])

    DEFAULT_FILE_STORAGE = "django_tenants.files.storage.TenantFileSystemStorage"

    SHARED_APPS = [
    "django_tenants",
    "sfe.common.apps.CommonConfig",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    ]

    TENANT_APPS = [
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django_bootstrap5",
    "django_bootstrap_icons",
    "bootstrap_modal_forms",
    "sfe.tenant.apps.TenantConfig",
    "sfe.tenant.email_controller.apps.EmailControllerConfig",
    ]

    INSTALLED_APPS = list(SHARED_APPS) + [app for app in TENANT_APPS if app not in SHARED_APPS]

    MIDDLEWARE = [
    "sfe.common.middleware.HealthCheckMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    ]

    if DEBUG:
    INTERNAL_IPS = ["localhost", ".localhost"]

    ROOT_URLCONF = "sfe.urls_tenant"
    PUBLIC_SCHEMA_URLCONF = "sfe.urls_public"

    TEMPLATES = [
    {
    "BACKEND": "django.template.backends.django.DjangoTemplates",
    "DIRS": [],
    "APP_DIRS": True,
    "OPTIONS": {
    "context_processors": [
    "django.template.context_processors.debug",
    "django.template.context_processors.request",
    "django.contrib.auth.context_processors.auth",
    "django.contrib.messages.context_processors.messages",
    "sfe.common.context_processor.version",
    "sfe.common.context_processor.default_domain",
    ],
    },
    },
    ]

    WSGI_APPLICATION = "sfe.wsgi.application"

    default_db = dj_database_url.config(engine="django_tenants.postgresql_backend")
    DATABASES = {
    "default": {
    "OPTIONS": {"pool": True},
    **default_db,
    }
    }
    DATABASE_ROUTERS = ("django_tenants.routers.TenantSyncRouter",)
    TEST_RUNNER = "django.test.runner.DiscoverRunner"

    AUTH_PASSWORD_VALIDATORS = [
    {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
    {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
    {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
    {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
    ]

    TENANT_MODEL = "common.SystemTenant"
    TENANT_DOMAIN_MODEL = "common.Domain"
    PUBLIC_SCHEMA_NAME = "public"

    LANGUAGE_CODE = "pl"
    LANGUAGES = [("pl", "Polski"), ("en", "English")]
    LOCALE_PATHS = (os.path.join(BASE_DIR, "locale"),)

    TIME_ZONE = "UTC"
    USE_TZ = True
    USE_I18N = True

    PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
    STATIC_URL = "/static/"
    STATIC_ROOT = os.path.join(PROJECT_ROOT, "static")

    LOGIN_URL = _("/login/")
    LOGOUT_REDIRECT_URL = "/"
    LOGIN_REDIRECT_URL = "/"
    SESSION_COOKIE_AGE = 86400

    DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
    STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

    IMAP_TIMEOUT = 60
    ADMINS = [("Damian Giebas", "damian.giebas@gmail.com")]
    MANAGERS = ADMINS

    FIRST_DAY_OF_WEEK = 1



    Project structure: [​IMG]

    Simple test setup:

    # External Dependencies
    from django.utils.timezone import now
    from django_tenants.test.cases import TenantTestCase
    from django_tenants.utils import schema_context

    # Current App
    from sfe.tenant.models.due_date import DueDate


    class DueDateModelTests(TenantTestCase):
    def setUp(self):
    super().setUp()

    def test_create_due_date(self):
    with schema_context(self.tenant.schema_name):
    DueDate.objects.create(date=now().date(), name="TestDueDate")

    assert DueDate.objects.all().count() == 1

    Continue reading...

Compartilhe esta Página