与psycopg2并行更新



在服务器上,我有一个API,它由一个或多个客户端调用。服务器几乎可以同时接收同一PostgreSQL属性的多条更新指令。这些请求不是在同一时间到达的,我只想一个接一个地执行它们。由于(Flask(API,我无法控制前一次调用是否结束,因此可以在前一次更新完成之前调用新的更新。除了psycopg2/postgresql之外,我希望能够对更新进行排队,并一个接一个地安静地进行更新(可能甚至不按顺序(,但它似乎不起作用。

以下是需要更新时在服务器上调用的函数的简化版本。如果重要的话,要更新的属性是一个JSONB对象。因此,有一个"路径"来确定要更新JSONB对象的哪一部分。所以API调用看起来是这样的:

def pg_update(data, path):
conn = psycopg2.connect(...) # always the same database.
cur = conn.cursor()
# JSONB update for a single selected row and column.
# 'column' and 'select_row' are determined with the parameters 'data' and 'path'.
command = (
f"""UPDATE MY_TABLE SET """
f"""{column} = jsonb_merge({column}, %s) """
f"""WHERE {select_row};"""
)
cur.execute(command, [Json(data)])
conn.commit()

当连续调用两次时,此调用会导致错误(在"cur.execute"处(:

psycopg2.errors.InternalError_: tuple concurrently updated

由于服务器一直在运行,所以我也可以在API调用之外定义conn;更新pg_;以便使用相同的psycopg2连接来处理所有调用。但是,当对同一属性请求两次更新时,我得到的是:

psycopg2.ProgrammingError: execute cannot be used while an asynchronous query is underway

我在psycopg2.connect中强制使用async_ = False,以防万一。没有变化。

总之,即使独立的、无法控制的客户端请求几乎同时请求这些更新,我如何允许一个又一个具有相同属性的多个更新?也许需要一个锁定机制?排队机制?

您可以使用SELECT FOR UPDATE机制。以下是一些简单的例子,可能会有所帮助。

最新更新