MagicStack / MagicStack/asyncpg

Concurrent queries on single connection

未关闭
#738 6 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

主要语言
Python
星标
8.1k
派生
468
PR 合并指标
30 天内没有已合并 PR

描述

* **asyncpg version**: 0.22.0
* **PostgreSQL version**: 13.2
* **Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
the issue with a local PostgreSQL install?**: local PostgreSQL install
* **Python version**: 3.9
* **Platform**: centos
* **Do you use pgbouncer?**: No
* **Did you install asyncpg with pip?**: Yes
* **If you built asyncpg locally, which version of Cython did you use?**:
* **Can the issue be reproduced under both asyncio and
[uvloop](https://github.com/magicstack/uvloop)?**: uvloop

from asyncpg.exceptions import InterfaceError

class CursorIterator:
def __init__(self, connection, prefetch, portal_name):
if prefetch <= 0:
raise InterfaceError("prefetch argument must be greater than zero")

self._connection = connection
self._prefetch = prefetch
self._portal_name = portal_name
self.rows = []

def __aiter__(self):
return self

async def __anext__(self):
if not self.rows:
self.rows = await self._connection.fetch(
f"FETCH {self._prefetch} FROM {self._portal_name}"
)

if self.rows:
return self.rows.pop(0)

raise StopAsyncIteration


class Cursor:
def __init__(self, connection, query, *args, prefetch=None):
self._connection = connection
self._args = args
self._prefetch = prefetch
self._query = query
self._portal_name = connection._get_unique_id("portal")

async def __aenter__(self):
await self._connection.execute(
f"DECLARE {self._portal_name} NO SCROLL CURSOR WITH HOLD FOR {self._query}",
*self._args,
)

prefetch = 50 if self._prefetch is None else self._prefetch
return CursorIterator(self._connection, prefetch, self._portal_name)

async def __aexit__(self, *args):
await self._connection.execute(f"CLOSE {self._portal_name}")

Several queries are run concurrently and I receive the following error. What can I do to fix the problem ?

File "asyncpg/protocol/protocol.pyx", line 321, in query
File "asyncpg/protocol/protocol.pyx", line 684, in asyncpg.protocol.protocol.BaseProtocol._check_state
asyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先阅读 asyncpg/protocol/protocol.pyx 中 BaseProtocol._check_state 附近的内容,并将其与提供的 Cursor 和 concurrent-query 示例进行比较。检查是否在并发使用同一个连接,并确定预期行为或文档范围;完成的标准应是确认能够复现,并与 maintainer 就方向达成一致。

由索引模型根据 Issue 内容生成。

评估

技术栈
postgresql, python
领域
databases
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
需要澄清
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。