Python 如何防止并发插入创建重复项?

Python 如何防止并发插入创建重复项?,python,sqlalchemy,celery,Python,Sqlalchemy,Celery,我有一个SQLAlchemy模型对象,如下所示: ResultModelBase = declarative_base() class Task(ResultModelBase): """Task result/status.""" id = sa.Column(sa.Integer, sa.Sequence("task_id_sequence"), primary_key=True, autoincr

我有一个SQLAlchemy模型对象,如下所示:

ResultModelBase = declarative_base()
class Task(ResultModelBase):
    """Task result/status."""

    id = sa.Column(sa.Integer, sa.Sequence("task_id_sequence"),
                   primary_key=True,
                   autoincrement=True)
    task_id = sa.Column(sa.String(255))
在两个独立的客户端进程中,运行此代码以创建具有唯一任务id的新实例;任务id只能有一个实例:

task = session.query(Task).filter(Task.task_id == task_id).first()
if not task:
    task = Task(task_id)
    session.add(task)
    session.flush()

如何重写此代码,使其自动创建具有指定ID的任务?

在代码块周围使用锁

# lock here
task = session.query(Task).filter(Task.task_id == task_id).first()
if not task:
    task = Task(task_id)
    session.add(task)
    session.flush()
# unlock here

你的问题不明确。数据库中存在设计缺陷。您不能通过自动递增的id定义行的唯一性。您必须有其他字段将其定义为唯一的(例如task_name+worker),然后通过以下字段创建任务:
task(task_name=smt,worker=smt)
-不要手动放置
task_id
-它将自动指定为下一个表id。autoinc主键仅用于查找和关系,但始终放置由其他表组成的唯一键。如果您不能找出哪些字段,那么您的表就没有标准化

现在,对于处理重复项插入的问题: session.flush()#执行以前的工作

session.flush()
try: 
    t = Task(task_name=smt, worker=smt)
    session.add()
    session.flush()
except sqlalchemy.exc.IntegrityError:
    # task already exists 
else:
    # task added to db

我更喜欢更实用的东西;首先,锁定什么?是的,在DB中添加约束绝对是正确的方法。
task\u id
应该被声明为唯一的(并且应该有一个索引以提高速度):
task\u id=sa.Column(sa.String(255),unique=True,index=True)
@THC4k:
unique=True
用于创建唯一索引,因此
index=True
是多余的。