Skip to main content
 首页 » 编程设计

python之Sqlalchemy 和 Python之返回 ID 的 upsert 语句

2025年05月04日13Terrylee

我正在编写一个 sqlalchemy upsert 语句,我想知道是否有办法从数据库中取回 ID? 到目前为止,这是我的代码:

def handle_events(self, events): 
    agg = [] 
    agg.extend(self._get_dicts(events)) 
    if not agg: 
        return 
    with DB.session(writable=True) as session: 
        response = session.execute(self._generate_upsert_stmnt(agg)) 
 
 
def _generate_upsert_stmnt(self, items): 
    model_class = models.MyModel 
    table = model_class.__table__ 
    insert_statement = sa.dialects.postgresql.insert(table, items) 
    upsert_statement = insert_statement.on_conflict_do_update( 
        index_elements=[table.c['id']], 
        set_={c.name: c for c in insert_statement.excluded if c.name != ["id", "my_model", "my_model_id"]} 
    ) 
    return upsert_statement 

此代码片段中的 session 是从 sqlalchemy 的 api(包装在上下文管理器中)的 sessionmaker 调用返回的对象。有没有办法让这个 upsert 语句返回所有的 id(插入和更新)?如果是这样,那段代码会是什么样子? 提前致谢。附:如果重要的话,数据库是 postgres。

请您参考如下方法:

最终我使用了 .returning(<column>)在我的 upsert 语句中,如下所示:

def _generate_upsert_stmnt(self, items): 
    model_class = models.MyModel 
    table = model_class.__table__ 
    insert_statement = sa.dialects.postgresql.insert(table, items) 
    upsert_statement = insert_statement.on_conflict_do_update( 
        index_elements=[table.c['id']], 
        set_={c.name: c for c in insert_statement.excluded if c.name !=  
        ["id", "my_model", "my_model_id"]}).returning(table.c['id']) 
    return upsert_statement 

然后像这样提取数据:

    def _extract_ids_from_resultproxy(self, result): 
        table = models.MyModel.__table__ 
        return [row[table.c.id] for row in result]