Django - 无法使用两个数据库进行测试(带有 gis 扩展的 postgres 和 mongoDB (Djongo)

Posted

技术标签:

【中文标题】Django - 无法使用两个数据库进行测试(带有 gis 扩展的 postgres 和 mongoDB (Djongo)【英文标题】:Django - Unable to test with two databases (postgres with gis extension and mongoDB (Djongo) 【发布时间】:2021-09-06 17:58:06 【问题描述】:

我无法使用 Django 的单元测试来测试两个数据库。

我的数据库配置:

DATABASES = 
'default': ,
'postgres': 
    'ENGINE': 'django.contrib.gis.db.backends.postgis',
    'NAME': "<name>",
    'USER': "<user>",
    'PASSWORD': "<pass>",
    'HOST': "localhost",
    'PORT': 5432,
,
'mongodb': 
    'ENGINE': 'djongo',
    'NAME': '<name>',
    'ENFORCE_SCHEMA': True,

我的简单测试:

from django.test import TestCase



class TestFormModel(TestCase):
    databases = 'postgres', 'mongodb'


    def test_generate_persistent_data_indexes(self):
        assert True

我得到的错误:

AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'

我迁移了两个数据库

当我将 postgres 数据库设置为 default 时,我得到:

self = <django.db.backends.utils.CursorWrapper object at 0x1132de580>
sql = 'SELECT "user_userdata"."id", "user_userdata"."user_profile", 
"user_userdata"."data", "user_userdata"."is_persistent" FROM "user_userdata" ORDER BY 
"user_userdata"."id" ASC', params = () 
ignored_wrapper_args = (False, 'connection': 
<django.contrib.gis.db.backends.postgis.base.DatabaseWrapper object at 0x112d96f70>, 
'cursor': <django.db.backends.utils.CursorWrapper object at 0x1132de580>)

    def _execute(self, sql, params, *ignored_wrapper_args):
        self.db.validate_no_broken_transaction()
        with self.db.wrap_database_errors:
            if params is None:
            return self.cursor.execute(sql)
            else:
>               return self.cursor.execute(sql, params)
E               django.db.utils.ProgrammingError: column user_userdata.data does not 
exist
E               LINE 1: ...r_userdata"."id", "user_userdata"."user_profile", 
"user_user...
E                                                                            ^

venv/lib/python3.8/site-packages/django/db/backends/utils.py:84: ProgrammingError

我的 MongoDB 模型:

class UserData(djongo_models.Model):
    id = djongo_models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user_profile = djongo_models.UUIDField()
    data = djongo_models.JSONField(default=)
    is_persistent = djongo_models.BooleanField(default=False)
    objects = djongo_models.DjongoManager()

更新: 我的数据库路由器在 allow_migrate 方法中指向了错误的数据库。来自 Postgres 的迁移正在应用于 MongoDB,这导致了一个问题。

(不)有趣的事实: model._meta.app_label 返回小写模型名称,我花了大约 2 个小时才弄对。

允许从我的路由器迁移方法:

只有来自用户应用的 UserData 模型正在使用 mongodb

    ROUTE_APP_LABEL = 'user'
    ROUTE_MODEL_LABELS = 'userdata'

    def allow_migrate(self, db, app_label, model_name=None, **hints):
    """
    Migrate specified models in specified apps to mongodb
    OR
    Migrate rest of the models if database is default (postgres)
    """
    if app_label == self.ROUTE_APP_LABEL and model_name in self.ROUTE_MODEL_LABELS:
        return db == 'mongodb'

    return db != 'mongodb'

【问题讨论】:

我也有同样的问题 :( 你试过单独测试数据库吗? 是的,但这也不起作用 @mazharAli 是的,我的数据库路由器在 allow_migrate 方法中指向错误的数据库。来自 postgres 的迁移正在应用于 mongodb,这导致了一个问题。 @MazharAli 是的,因为未执行迁移。这就是您无法访问某些列的原因。调试您的路由器并设置为应设置的值。 @MazharAli 我在原始问题中添加了我的路由器配置,检查一下。 MongoDB 在默认设置中不需要迁移。 【参考方案1】:

我设法解决了这个问题。

我的数据库路由器在 allow_migrate 方法中指向了错误的数据库。来自 Postgres 的迁移正在应用于 MongoDB,这导致了一个问题。

(不)有趣的事实: model._meta.app_label 返回小写模型名称,我花了大约 2 个小时才弄对。

允许从我的路由器迁移方法:

只有来自用户应用的 UserData 模型正在使用 mongodb

    ROUTE_APP_LABEL = 'user'
    ROUTE_MODEL_LABELS = 'userdata'

    def allow_migrate(self, db, app_label, model_name=None, **hints):
    """
    Migrate specified models in specified apps to mongodb
    OR
    Migrate rest of the models if database is default (postgres)
    """
    if app_label == self.ROUTE_APP_LABEL and model_name in self.ROUTE_MODEL_LABELS:
        return db == 'mongodb'

    return db != 'mongodb'

【讨论】:

以上是关于Django - 无法使用两个数据库进行测试(带有 gis 扩展的 postgres 和 mongoDB (Djongo)的主要内容,如果未能解决你的问题,请参考以下文章

带有加载夹具的 Django 单元测试,用于解决几个相关的应用程序问题

Django - 无法进行迁移,MySQL 5.7.19,Py 3.6.2 [重复]

带有 django 的 Docker-compose 无法将主机名“db”转换为地址:名称或服务未知

Django jwt 通道无法验证

错误:当我在 React 中尝试使用 Jest 进行测试时,无法找到带有文本的元素

Django 测试冻结在数据库创建