You need to enable JavaScript to run this app. SQLAlchemy1.4命令式映射下内存PostgreSQL测试未映射报错如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy1.4命令式映射下内存PostgreSQL测试未映射报错如何解决?

问题根因

你的报错核心是User类没有完成ORM映射,原因出在测试的session fixture逻辑:

  1. 你在fixture中调用clear_mappers()会清空所有已注册的ORM映射关系,包括项目启动时myapp/orm.py执行map_imperatively注册的User映射
  2. 清空后仅调用configure_mappers()只对声明式映射的类生效,你用的命令式映射不会自动重新注册,最终导致User类处于未映射状态,触发UnmappedInstanceError报错。

修改方案

1. 封装命令式映射注册逻辑(推荐,避免重复代码)

修改myapp/orm.py,把映射操作封装为可复用函数,同时去掉冗余的Metadata定义:

from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import registry
from myapp import model

mapper_registry = registry()
# 直接使用registry自带的metadata,不需要单独定义
metadata = mapper_registry.metadata

user_table = Table(
    'tb_user',
    metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)),
    Column('fullname', String(50)),
    Column('nickname', String(12))
)

def start_mappers():
    """手动注册命令式映射,测试清空映射后可调用该函数重新注册"""
    mapper_registry.map_imperatively(model.User, user_table)

# 模块加载时默认执行注册,不影响生产环境使用
start_mappers()

2. 修复测试session fixture逻辑

修改tests/test_postgresql_inmemory.py中的session fixture,清空映射后重新调用映射注册函数,删除无效的configure_mappers()调用:

@pytest.fixture
def session(in_memory_db):
    clear_mappers()
    # 重新注册所有命令式映射
    from myapp.orm import start_mappers
    start_mappers()
    Session = sessionmaker(bind=in_memory_db)
    session = Session()
    yield session
    clear_mappers()

3. 修复测试查询语法(可选,消除警告)

SQLAlchemy 1.4+要求原生SQL必须用text()包裹,否则会触发警告,修改测试用例:

def test_User_mapper_can_add(session):
    user = model.User(fullname="John Smith")
    session.add(user)
    session.commit()
    rows = list(session.execute(text("SELECT fullname FROM tb_user")))
    assert rows == [("John Smith",)]

修改完成后重新运行测试即可正常通过。


内容的提问来源于stack exchange,提问作者Lionel Hamayon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 03:45:04