Django Channels Postgres InterfaceError:连接已关闭 [英] Django Channels Postgres InterfaceError: connection already closed
问题描述
我似乎无法在这里解决这个问题。我正在按照文档中的说明 >。我通常会使用Django默认的单元测试,但是由于Channels需要使用pytest,因此我正在使用它,但仍希望保持编写测试的类结构。
I can't seem to wrap my head around the issue here. I'm writing tests for my Channel Consumers following the description in the docs. I'd normally use the Django default unittest but since Channels requires using pytest, I'm using it but will still like to maintain the class structure of writing tests.
I在编写类似于unittest的设置方法时遇到问题,该方法将用于初始化测试属性。我尝试了方法固定装置,使用 autouse = true ,但是它们似乎都不起作用,因为我无法在测试方法中访问实例属性。最后,我只是决定编写 set_up
实例方法,并为每个类手动调用它。这是我到目前为止的内容:
I had issues with writing the setup method similar to unittest which I would use to initialize the test attributes. I tried method fixtures, class fixtures using autouse=true, but none of them seemed to work as I couldn't access the instance attributes in the test methods. Finally I just decided to write the set_up
instance method and manually call it for each class. This is what I have so far:
@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
问题是我不断得到 psycopg2.InterfaceError:当我的使用者尝试使用
。它使用 connect
方法内的代码访问数据库时,连接已关闭 database_sync_to_async
,并且在我手动测试它时效果很好。
The issue is that I keep getting psycopg2.InterfaceError: connection already closed
when my consumer tries to access the database in it's code inside the connect
method. It uses database_sync_to_async
and works pretty well when I'm manually testing it.
具体来说,<引发错误的code> connect 方法如下所示:
Specifically, the line in the connect
method that raises the error looks like this:
await database_sync_to_async(user.inbox.increment_connections)().
不确定到底是什么问题,因为 database_sync_to_async
应该正确清理旧的连接,以便可以正确地创建新的连接。
Not sure what exactly the issue is as database_sync_to_async
should properly clean up old connections so that new ones can be properly created.
任何帮助将不胜感激。
推荐答案
显然我在看错地方。问题在这条线上:
Apparently I was looking at the wrong place. The issue was on this line:
await database_sync_to_async(user.inbox.increment_connections)()
。
收件箱
是相关管理器,因此它会尝试在实际的 database_sync_to_async $ c之前获取它$ c>,它失败,因为它需要数据库调用。
inbox
is a related manager so it tries to fetch it before the actual database_sync_to_async
and it fails as it requires a db call.
我尝试了这个 await database_sync_to_async(user).inbox.increment_connections()
,但由于它包装了一个方法而不是一个属性,所以它不起作用,所以我最终要做的是使用 prefetch_related
来获取收件箱
。这样, user.inbox
不再需要数据库调用,并且可以正常工作
I tried this await database_sync_to_async(user).inbox.increment_connections()
and it didn't work since it wraps a method, not an attribute so what I ended up doing was to use prefetch_related
to get the inbox
during the authentication. In that way user.inbox
no longer requires a db call and it works fine
这篇关于Django Channels Postgres InterfaceError:连接已关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!