From 09682245f5e7defac98633a0ed2beb0bed45e410 Mon Sep 17 00:00:00 2001 From: zikai Date: Tue, 28 Jul 2026 04:32:56 +0000 Subject: [PATCH] =?UTF-8?q?fix(database):=20init=5Fdb=5Fschema=20=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=20SQLAlchemy=202.0.x=20=E7=9A=84=20frozenset=20mapper?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Base.registry.mappers 在 SQLAlchemy 2.0.x 是 frozenset(装 Mapper 对象), 而非 dict({table: mapper}),原 .items() 调用会抛 'frozenset' object has no attribute 'items' 导致启动期建表校验失败。 改为统一取 Mapper,用 local_table.name 取表名、columns 取列,兼容 dict 与 frozenset 两种形态。 --- app/database.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/database.py b/app/database.py index ef4d41b..27a6810 100644 --- a/app/database.py +++ b/app/database.py @@ -78,7 +78,16 @@ def init_db_schema() -> None: inspector = inspect(engine) missing: list[str] = [] - for table, mapper in Base.registry.mappers.items(): + # Base.registry.mappers 在不同 SQLAlchemy 版本中既可能是 dict({table: mapper}), + # 也可能是 frozenset(直接装 Mapper 对象)。统一取 Mapper,用 local_table 取表名、 + # columns 取模型声明的列,兼容两种形态。 + mappers = Base.registry.mappers + if hasattr(mappers, "values"): # dict 形态 + mapper_iter = mappers.values() + else: # frozenset 形态(SQLAlchemy 2.0.x) + mapper_iter = iter(mappers) + for mapper in mapper_iter: + table = mapper.local_table.name if not inspector.has_table(table): continue db_cols = {c["name"] for c in inspector.get_columns(table)}