【问题标题】:Postgresql - Insert into where not exists using sqlalchemy's INSERT from SELECTPostgresql - 使用 sqlalchemy 的 INSERT from SELECT 插入不存在的位置
【发布时间】:2013-09-01 07:41:18
【问题描述】:

正如here 指出的那样,可以使用 postgresql 9.1+ 执行以下操作

INSERT INTO example_table
    (id, name)
SELECT 1, 'John'
WHERE
    NOT EXISTS (
        SELECT id FROM example_table WHERE id = 1
    );

我一直在玩 sqlalchemy 0.9 版,他们引入了 INSERT from SELECT 方法,理论上应该可以处理上述问题。

有可能吗?如果有,怎么做? (因为我想利用使用原始 sql 时未返回的 result.inserted_primary_key)

我如何将 bindparams 用于“from_select”部分,因为我似乎可以使用它的唯一方法是在选择中使用表列时。

例如

insrt = example_table.insert().
    from_select(['id', 'name'],
    example_table.select().
    where(~exists(select([example_table.c.id],
    example_table.c.id == 1))))

result = session.execute(insrt)

if result.is_insert:
    print 'do something with result.inserted_primary_key'

【问题讨论】:

  • 只有在您已经知道主键并且如果它不存在时想要创建它时,执行您给出的命令才是安全的。如果您使用非唯一键执行此操作,那么它会受到可能导致多个插入同时成功运行的竞争条件的影响。即使是这样,该命令也不一定会成功,如果它与另一个并发插入竞争,它可能会失败并出现唯一的违规错误。要了解有关此内容的更多信息,请阅读此处关于堆栈溢出的 PostgreSQL 上的 upsert 的许多其他讨论。
  • 很多很多很多的讨论。我使用的关键是独一无二的,并且不应该(希望)并发插入有任何问题。我在这里遇到的问题是 sqlalchemy 的语法,并让它在选择中使用我自己的参数(通过 bindparams 或任何其他方式)而不是使用表列
  • 它似乎也适用于 8.4.11

标签: python postgresql sqlalchemy insert-update


【解决方案1】:
from sqlalchemy import *

"""
INSERT INTO example_table
    (id, name)
SELECT 1, 'John'
WHERE
    NOT EXISTS (
        SELECT id FROM example_table WHERE id = 1
    );
"""

m = MetaData()

example_table = Table("example_table", m,
                        Column('id', Integer),
                        Column('name', String)
                    )

sel = select([literal("1"), literal("John")]).where(
           ~exists([example_table.c.id]).where(example_table.c.id == 1)
      )

ins = example_table.insert().from_select(["id", "name"], sel)
print(ins)

输出:

INSERT INTO example_table (id, name) SELECT :param_1 AS anon_1, :param_2 AS anon_2 
WHERE NOT (EXISTS (SELECT example_table.id 
FROM example_table 
WHERE example_table.id = :id_1))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多