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
相关产品推荐
相关产品推荐

