我正在尝试使用SQLAlchemy核心创建一个仅在DB(postgres)中命中一次的查询,如果它不存在则插入一行。
以下是查询的一部分
WITH new_values (id, field) as (
values
(1, 1),
(2, 12),
(3, 13),
(4, 14)
)
INSERT INTO table1 (id, field)
SELECT id, field
FROM new_values
WHERE NOT EXISTS (SELECT 1
FROM table1 as up
WHERE up.id = new_values.id);
我很困惑:
SELECT 1
?我想使用核心API并避免直接执行。
PS: 我想在单个事务中放入的完整查询是
WITH upsert AS (
UPDATE table2
SET field1=field1+1
WHERE id=1234 AND field2=42
RETURNING *
)
INSERT INTO table2 (id, field1, field2)
SELECT 1234, 1, 42
WHERE NOT EXISTS (SELECT 1 FROM upsert);
WITH new_values (id, field) as (
values
(1, 1),
(2, 12),
(3, 13),
(4, 14)
)
INSERT INTO table1 (id, field)
SELECT id, field
FROM new_values
WHERE NOT EXISTS (SELECT 1
FROM table1 as up
WHERE up.id = new_values.id);
编辑: 模型
table1 = Table('table1', metadata,
Column('id', Integer, primary_key=True),
Column('field', Integer))
table2 = Table('table2', metadata,
Column('id', Integer, primary_key=True),
Column('field1', Integer),
Column('field2', Integer))
答案 0 :(得分:2)
SQLAlchemy尚未直接支持此Postgres语法。几年前实际上存在一个问题,但它有近期的历史和优先级的提高。见https://bitbucket.org/zzzeek/sqlalchemy/issues/2551/apparently-inserts-and-update-delete-can
或者,定义text()
的{{1}}项可以columns()
调用它们,所以我想了一段时间,如果将cte()
转换为update
,这可能会有效带有绑定参数的普通sql。但是,当CTE与with
select_from
相关联时,很难让SQLAlchemy正确地将insert
置于查询的顶层。简而言之,在上述问题得到解决之前,我认为最好不要尝试将此方法与SQLAlchemy核心一起使用 - 使用SQL或搜索不同的upsert方法。