You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLModel多租户场景下修改Schema后事务提交未写入数据库问题排查

SQLModel + FastAPI多租户(多Schema)数据未持久化问题

背景

开发基于SQLModel的FastAPI多租户应用,采用多Schema架构,需动态切换Schema。

Schema定义

租户表模型继承自包含Schema配置的基类:

class SysEmailModel(BaseTenantSchemaModel, table=True):
    # 模型字段定义

基类通过metadata指定默认Schema:

class BaseTenantSchemaModel(BaseSharedSchemaModel, table=False):
    metadata = MetaData(
        schema="agip_tenant"
    )

选择metadata而非__table_args__,避免关联关系中重复指定Schema名称。

原Schema切换方式

通过会话连接设置schema_translate_map实现Schema映射:

def getSession(which):
    # database_session_tenant是已创建引擎的会话
    connectable = database_session_tenant.connection(
        execution_options={
            "schema_translate_map": {"agip_tenant": "SOME_NAME"}
        }
    )

    return Session(connectable)

问题现象

创建记录并提交事务后,数据仅存在于应用内存,未写入数据库:

session = getSession(tenant)
row = SysEmailModel(
    # 字段赋值
)

a = session.query(SysEmailModel).all()
print(a) # 输出1条数据,符合预期
session.add(row)
print(row) # 输出无ID的记录,符合预期
session.commit()
session.refresh(row)
print(row) # 输出带ID的记录,ID自增正确
b = session.query(SysEmailModel).all()
print(b) # 输出2条数据,符合预期

但直接在数据库执行select语句仅能查到1条数据。

疑问

  • 问题出在哪里?
  • 是否需要在execution_options中添加更多参数?

使用的依赖版本

  • sqlmodel==0.0.14
  • pydantic==1.10.13
  • pydantic_core==2.10.1
  • SQLAlchemy==2.0.23
  • sqlalchemy2-stubs==0.0.2a36
  • fastapi==0.105.0

临时解决方案及新疑问

改为直接基于引擎设置schema_translate_map创建会话:

engine = create_engine(...)
schema_translate_map = {"agip_tenant": "SOME_NAME"}
connectable = engine.execution_options(schema_translate_map=schema_translate_map)

return Session(connectable)

但产生新疑问:

  • 这种方式是否会导致连接数过多?
  • 是否需要每次调用后手动关闭会话?

内容的提问来源于stack exchange,提问作者Edgar Koster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:11:02