在使用pytest-django进行测试期间,Django连接对象没有看到第二个数据库的表

时间:2018-04-14 20:32:25

标签: django pytest pytest-django

底线:我的Django连接对象在使用pytest-django进行测试时没有看到第二个数据库的表关系。

概述: 我有一个问题,我的Django连接对象似乎得到错误的数据库信息。当我在“顾客”的桌子上查询时,我偶然发现了这个问题。 DB和Django告诉我这种关系不存在。使用settings.py数据库部分设置如下:

DATABASES = {
    'default': {
        'NAME': 'user_data',
        'ENGINE': 'django.db.backends.postgres',
        'USER': 'postgres_1',
        'PASSWORD': 'superS3cret'
    },
    'customers': {
        'NAME': 'customer_data',
        'ENGINE': 'django.db.backends.postgres',
        'USER': 'postgres_1',
        'PASSWORD': 'superS3cret'
    }
}

以下两个游标都会获得“默认”信息。数据库,当我运行' pytest'在目录中:

sql = """SELECT table_name FROM information_schema.tables WHERE table_nameschema='public'"""

default = connections["default"].cursor()
default.execute(sql)
raw_data = default.fetchall()
sql_columns = [col[0] for col in default.description]
df1 = pd.DataFrame(raw_data, columns=sql_columns)

customers = connections["customers"].cursor()
customers.execute(sql)
raw_data = customers.fetchall()
sql_columns = [col[0] for col in customers.description]
df2 = pd.DataFrame(raw_data, columns=sql_columns)

df1和df2的结果完全相同:只有'默认'中的表名。数据库。

这发生在pytest-django并使用第二个Postgres数据库,但有时仅

在上面的查询中,我认为df1和df2是不同的,只要'默认'和'客户'数据库是不同的。但是,有时连接光标没有正确地看到'第二个数据库中的所有信息。

奇怪的是,当我打印时,连接设置显示不同:

print(connections.databases)

'连接' object包含两个不同的DB,但其中一个是" test" D B。 print语句产生一个字典,但请注意" test_customers ":

(pdb) { 'default': { <conn info>}, 'test_customers': { <conn info> } }

似乎Django正在尝试建立一个测试数据库,失败,并且没有通过测试,因为“test_customers&#39;不像生产中那样存在。

如何解决此问题,以便pytest-django在测试期间始终可以看到第二个数据库(客户)中的表格?我在设置和拆卸数据库时遇到了什么问题吗?

更新:阅读pytest-django docs on DB creation/re-use让我指出了正确的方向。但是,我对这部分文档感到有些不安:

  

目前pytest-django并不专门支持Django   多数据库支持。但是,您可以使用普通的Django TestCase   实例使用其multi_db支持。

     

如果您对支持多个数据库的最佳API有任何想法   直接在pytest-django请联系我们,我们感兴趣   最终支持这个,但不确定只是跟随Django的   方法

2 个答案:

答案 0 :(得分:1)

pytest-django does not support multiple databases。当我尝试使用多个数据库和参数--reuse-db / --create-db时,结果是,它有时会起作用(所有数据库都已创建且可以正确使用),有时它不起作用(数据库是没有创建或Django抱怨数据库已经存在)。

恕我直言有两种选择: 1)不要在Django上使用pytest; 2)简化您的测试,因此您不需要多个数据库。对于选项2)我使用此设置:

正常settings

DATABASES = {
    'default': ...,
    'secondary': ...,
}

pytest.ini

[pytest]
...
DJANGO_SETTINGS_MODULE=my_app.settings.test
...

test.py

# Import all from normal settings
from .base import *

DATABASES.pop('secondary')
# This will route all queries and migrations to the default DB
DATABASE_ROUTERS = []

答案 1 :(得分:0)

在test_settings.py->猴子补丁中

from django.db.models.query import QuerySet, RawQuerySet
queryset_using = QuerySet.using
raw_queryset_using = RawQuerySet.using


def new_queryset_using(self, alias):
    return queryset_using(self, 'default')


def new_raw_queryset_using(self, alias):
    return raw_queryset_using(self, 'default')


QuerySet.using = new_queryset_using
RawQuerySet.using = new_raw_queryset_using