Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 高效更新,失败时插入,使用sqlalchemy_Python_Python 2.7_Sqlalchemy - Fatal编程技术网

Python 高效更新,失败时插入,使用sqlalchemy

Python 高效更新,失败时插入,使用sqlalchemy,python,python-2.7,sqlalchemy,Python,Python 2.7,Sqlalchemy,我基本上需要做一个插入。。。在重复密钥更新时但是行在99.9…%的时间内已经存在。因此,我真正想做的是更新,捕获异常并插入 在sqlalchemy中,我通常会执行以下操作: new_obj = MyModel(the_pk=id) new_obj = MyModel.__table__.c.some_val + val session.merge(new_obj) 不过我注意到,当我调用session.mergesqlalchemy时,会执行一个SELECT,如果我知道我几乎总是UPDATE,

我基本上需要做一个
插入。。。在重复密钥更新时
但是行在99.9…%的时间内已经存在。因此,我真正想做的是
更新
,捕获异常并
插入

在sqlalchemy中,我通常会执行以下操作:

new_obj = MyModel(the_pk=id)
new_obj = MyModel.__table__.c.some_val + val
session.merge(new_obj)
不过我注意到,当我调用
session.merge
sqlalchemy时,会执行一个
SELECT
,如果我知道我几乎总是
UPDATE
,那么这是低效的。除了编写原始SQL(我对此很满意),还有什么方法可以改进这一缺点吗?我只是想知道我是否错过了一些炼金术技巧

另外,在进行合并之后,如果在刷新/提交会话之前存在一个PK冲突的行,会发生什么情况?我假设选择是为了确定sqlalchemy以后是否需要执行
插入
更新

耦合选项: 1) 绕过SA并执行实际的合并语句,如果dbms支持,则使用replace语句。这是用于添加合并语句的SA票据,其中还包括替换语句的收据:

2) 简单的方法是,进行更新,您将得到更新后的行数,如果是0,则执行插入


如果您有多个writer,则第二个选项可能会有问题,因为两个writer可以更新,并且都得到0行更新,然后两个writer插入中只有一个会成功。不确定这是否是您的问题,但需要注意。

您使用的是什么数据库?MySQL、Postgresql、sqlite等…?@Tony MySQL与InnoDB引擎如果有任何区别,给定MySQL,我们试图避免插入
。。。在重复键上…
,因为它首先尝试插入,而行几乎总是存在的,所以效率很低。我走了第二条路线,添加了一个
,除了IntegrityError
,以减轻创建时的竞争条件。@Endophage我也会这样做。如果允许删除,那么您需要执行类似于
的操作,而True:{try:update()else:break}
,因为在实际成功之前,多个编写器/删除器可能会导致任意数量的整数错误。