SQLAlchemy: WITH new_values (id, field) as ( values (..., ...) )

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)

我很困惑:

  • 如何使用指定的值创建 CTE 表达式(我只找到了带有子查询的示例)
  • 我怎么办SELECT 1
  • 如何在插入中添加 where?

我想使用核心 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)

Jas*_*n S 4

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