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
tasks
表。位于Tssh
的用户进入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”
状态)<坚强>但是要坚强