Mak*_*s_F 5 python sql sqlalchemy
我正在尝试使用 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);
Run Code Online (Sandbox Code Playgroud)
我很困惑:
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);
Run Code Online (Sandbox Code Playgroud)
编辑:模型
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))
Run Code Online (Sandbox Code Playgroud)
SQLAlchemy(尚未)直接支持此 Postgres 语法。实际上,几年前就提出了一个问题,但它的历史最近并且优先级有所提高。请参阅https://bitbucket.org/zzzeek/sqlalchemy/issues/2551/apparently-inserts-and-update-delete-can
或者,text()已定义的项目columns()可以cte()调用它们,所以我想了一段时间,如果将它们update转换为带有绑定参数的纯 sql,这可能会起作用。然而,当 CTE 与a关联时,很难让 SQLAlchemy 正确地将 放置with在查询的顶层。简而言之,在上述问题得到解决之前,我认为您最好不要尝试在 SQLAlchemy 核心中使用这种方法——要么使用 SQL,要么搜索不同的 upsert 方法。select_frominsert