Python 使用更新的多个数据库连接。。。正在返回,似乎没有更新任务表中的行 前言

Python 使用更新的多个数据库连接。。。正在返回,似乎没有更新任务表中的行 前言,python,postgresql,psycopg2,isolation-level,autocommit,Python,Postgresql,Psycopg2,Isolation Level,Autocommit,我想并行处理数据库表中列出的任务。不寻找工作代码 设置 1个PostgreSQL数据库服务器D 1个处理服务器P 1个用户终端T 使用Python 3.6、psycopg2.7.6和PostgreSQL 11 D保存包含要处理的数据的表和一个tasks表。位于Tssh的用户进入P,可以发出以下命令: python -m core.utils.task 这个task.py脚本本质上是一个while循环,它从D上的tasks表中获取一个状态为“new”的任务t,直到没有新任务为止。任务t基本上

我想并行处理数据库表中列出的任务。不寻找工作代码

设置
  • 1个PostgreSQL数据库服务器D
  • 1个处理服务器P
  • 1个用户终端T
使用Python 3.6、psycopg2.7.6和PostgreSQL 11

D保存包含要处理的数据的表和一个
tasks
表。位于T
ssh
的用户进入P,可以发出以下命令:

python -m core.utils.task
这个
task.py
脚本本质上是一个
while
循环,它从D上的
tasks
表中获取一个状态为“new”的任务
t
,直到没有新任务为止。任务
t
基本上是另一个名为
do\u something(t)
的函数的一组参数
do_something(t)
本身将与D建立许多连接,以获取需要处理的数据,并在任务完成后将任务状态设置为“完成”while循环重新开始并获得新任务

为了多次运行
python-mcore.utils.task
,我打开了多个
ssh
连接。不太好,我知道<代码>线程化或
多处理
会更好。但是他只是为了测试我是否可以运行上面提到的命令两次

有一个脚本管理所有数据库交互,名为
pgsql.py
,它是获取任务所需的,然后通过
do\u something(t)
。我从中改编了一个单身模式

伪代码(大部分) task.py

导入mymodule
导入pgsql
def main():
尽管如此:
r、 c=pgsql.SQL。选择_task()#行和列
task=dotdict(dict(zip(c,r[0]))
mymodule.do_某事(任务)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
mymodule.py

导入pgsql
def do_某事(t):
input=pgsql.SQL.get\u映像(t.table、t.schema、t.image\u id、t.image\u目录)
一些其他功能(输入)
pgsql.SQL.task_状态(t.task_id,'done')
pgsql.py

将psycopg2导入为pg
类博士后(对象):
“改编自https://softwareengineering.stackexchange.com/a/358061/348371"""
_实例=无
定义新的(cls):
如果cls.\u实例为无:
cls.\u实例=对象.\u新\u(cls)
db_config={'dbname':'dev01','host':'XXXXXXXX',
“密码”:“yyyy”,“端口”:5432,“用户”:“管理员”}
尝试:
打印('连接到PostgreSQL数据库…')
connection=Postgres.\u instance.connection=pg.connect(**db\u config)
connection.set_会话(隔离级别='READ COMMITTED',autocommit=True)
除异常作为错误外:
打印('错误:未建立连接{}'。格式(错误))
Postgres.\u实例=无
其他:
打印('已建立连接')
返回cls.\u实例
定义初始化(自):
self.connection=self.\u instance.connection
def查询(自我,查询):
尝试:
将self.connection.cursor()作为cur:
当前执行(查询)
rows=cur.fetchall()
cols=[desc[0]表示当前描述中的描述]
除异常作为错误外:
打印('执行查询{}时出错,错误:{}'。格式(查询,错误))
一无所获
其他:
返回行、列
定义(自我):
self.connection.close()
db=Postgres()
类SQL():
def select_任务():
s=”“”
更新schema.tasks
设置状态='ready'
其中task_id=(选择task_id
从schema.tasks
其中tasks.status='new'
限制(1)
返回*
;
“”。格式(m=模式)
返回Postgres.query(db,s)
def任务_状态(id,状态):
s=”“”
更新
schema.tasks
设置
状态=“{s}”
哪里
tasks.task_id='{id}'
;
“”。格式(s=状态,
id=id)
返回Postgres.query(db,s)
问题 这适用于一个
ssh
连接。任务从数据库中检索并处理,一旦完成,任务将设置为“完成”。一旦我在第二个终端中打开第二个
ssh
连接来运行
python-m core.utils.task
(也就是说,并行运行),两个终端中都会处理任务表中完全相同的行,忽略它们已被更新

问题:
你有什么建议可以让它发挥作用?有数百万个任务,我需要并行运行它们。在实现
threading
multi-processing
之前,我想先用多个
ssh
连接来测试它,这不是个好主意吗?我在
psycopg2
set_session()
中摆弄了
隔离级别和
autocommit
设置,但运气不好。我检查了数据库服务器中的会话,可以看到
python-mcore.utils.task
的每个进程都有自己的PID,只连接一次,与此单例模式完全相同。任何关于如何处理此问题的想法或建议都将不胜感激

主要问题是执行一项任务不是原子操作。因此,在不同的ssh会话中,同一任务可以处理多次

在此实现中,您可以尝试为任务使用
“INPROGRESS”
状态,以避免检索已在处理的任务(使用
“INPROGRESS”
状态)<坚强>但是要坚强