Django channel Postgres InterfaceError : connection already closed

标签 django postgresql pytest python-asyncio django-channels

我似乎无法解决这里的问题。我正在按照 description in the docs 为我的 channel 消费者编写测试.我通常会使用 Django 默认的 unittest,但由于 Channels 需要使用 pytest,我正在使用它,但仍然希望保持编写测试的类结构。

我在编写类似于 unittest 的设置方法时遇到了问题,我将使用它来初始化测试属性。我试过 method fixtures , class fixtures 使用 autouse=true ,但它们似乎都不起作用,因为我无法访问测试方法中的实例属性。最后我决定编写 set_up 实例方法并为每个类手动调用它。这是我目前所拥有的:

@pytest.mark.django_db
@pytest.mark.asyncio
class TestChatConsumer(object):

    @database_sync_to_async
    def set_up(self):

        self.user = UserFactory()
        self.api_client = APIClientFactory()
        self.token = TokenFactory(user=self.user)

        self.credentials = {
            'AUTHORIZATION': self.token.key,
            ...
        }

        self.credentials_params = '&'.join(['{}={}'.format(k, v) for k, v in self.credentials.items()])
        self.authless_endpoint = '/api/v1/ws/'
        self.endpoint = self.authless_endpoint + '?' + self.credentials_params

    async def test_connect_without_credentials(self):
        await self.set_up()
        communicator = WebsocketCommunicator(application, self.authless_endpoint)
        connected, subprotocol = await communicator.connect()
        assert not connected

    async def test_connect_with_credentials(self):
        await self.set_up()
        communicator = WebsocketCommunicator(application, self.endpoint)
        connected, subprotocol = await communicator.connect()
        assert connected

问题是,当我的消费者尝试在 connect 方法内的代码中访问数据库时,我不断收到 psycopg2.InterfaceError: connection already closed 。它使用 database_sync_to_async 并且在我手动测试时运行良好。

具体来说,connect 方法中引发错误的行如下所示:

await database_sync_to_async(user.inbox.increment_connections)().

不确定究竟是什么问题,因为 database_sync_to_async 应该正确清理旧连接,以便正确创建新连接。

非常感谢任何帮助。

最佳答案

显然我看错地方了。问题出在这一行:

等待 database_sync_to_async(user.inbox.increment_connections)()

inbox 是一个相关的管理器,因此它尝试在实际的 database_sync_to_async 之前获取它,但由于需要调用数据库而失败。

我试过这个 await database_sync_to_async(user).inbox.increment_connections() 但它不起作用,因为它包装了一个方法,而不是一个属性,所以我最终做的是使用 prefetch_related 在认证时获取inbox。这样一来,user.inbox 就不再需要 db 调用了,而且工作正常

关于Django channel Postgres InterfaceError : connection already closed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54192519/

相关文章:

Django:用户之间的关系(存储唯一对/组合)

sql - 在分组/聚合期间连接/合并数组值

postgresql - 简单的 postgres 函数

python - 在测试套件结束时运行缓慢的 Pytest 命令

python - pytest中fixture和yield_fixture的区别

Django 压缩机不使用设置中的 STATICFILES_FINDER

python - tuple'对象没有属性 'get'

postgresql - 在 PostgreSQL 中为列的不同值创建索引

python - pytest:指定pytest.ini位置的环境变量

python - Django Rest Framework 中的批量更新数据