Strawberry GraphQL应用中SQLAlchemy_i18n创建翻译报错求助
问题排查与解决方案
针对你遇到的AttributeError: 'NoneType' object has no attribute 'get_all_pending'错误,结合SQLAlchemy-i18n + Strawberry GraphQL的场景,核心原因是SQLAlchemy-i18n的翻译上下文或关联对象未正确初始化,以下是具体排查步骤:
1. 检查SQLAlchemy-i18n初始化时机
确保在所有模型定义之前执行make_translatable初始化,且配置正确的 locales 列表:
from sqlalchemy_i18n import make_translatable # 必须放在模型定义前执行 make_translatable(options={ 'locales': ['zh-CN', 'en'], # 匹配你的业务需求 'default_locale': 'zh-CN' })
如果初始化晚于模型定义,翻译扩展无法绑定到SQLAlchemy元数据,会导致翻译对象关联失败。
2. 验证主模型与翻译模型的关联配置
主模型(Category)需明确翻译配置:
from sqlalchemy import Column, Integer, ForeignKey from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Category(Base): __tablename__ = 'category' # 必须指定翻译模型类名和可翻译字段 __translatable__ = { 'class': 'CategoryTranslation', 'fields': ['name', 'description'] } id = Column(Integer, primary_key=True) # 非翻译字段...
翻译模型(CategoryTranslation)需正确关联主模型:
class CategoryTranslation(Base): __tablename__ = 'category_translation' # 复合主键:id + locale id = Column(Integer, primary_key=True) locale = Column(String(10), primary_key=True) # 可翻译字段,需与主模型__translatable__['fields']对应 name = Column(String(255)) description = Column(String(500)) # 外键关联主模型 category_id = Column(Integer, ForeignKey('category.id')) category = relationship( 'Category', backref=backref('translations', cascade='all, delete-orphan') )
注意翻译模型必须使用复合主键,且外键关联和反向引用配置完整,否则无法自动创建关联的翻译对象。
3. 确认Locale上下文在请求中有效
Strawberry GraphQL是请求级上下文,全局设置的locale可能无法穿透到请求处理流程中,需在每个突变/查询处理前显式绑定locale:
from sqlalchemy_i18n import force_locale from strawberry.types import Info @strawberry.type class Mutation: @strawberry.mutation def create_category(self, info: Info, name: str, locale: str = "zh-CN") -> CategoryType: # 在会话操作前强制绑定当前请求的locale with force_locale(locale): db = info.context["db"] category = Category() # 直接赋值翻译字段(会自动关联到当前locale的翻译对象) category.name = name db.add(category) db.commit() db.refresh(category) return CategoryType.from_orm(category)
如果仅在会话初始化时设置一次全局locale,在请求上下文切换时可能丢失,导致翻译对象无法正确初始化。
4. 检查实例创建时的翻译字段赋值
避免直接操作translations字典,优先通过主模型的代理属性赋值(SQLAlchemy-i18n会自动创建对应的翻译对象):
# 正确方式 category = Category() category.name = "数码产品" # 自动绑定到当前locale的CategoryTranslation # 错误方式(可能导致翻译对象未初始化) category.translations['zh-CN'] = CategoryTranslation(name="数码产品")
直接操作translations如果未正确初始化关联,会导致内部上下文找不到翻译对象,触发NoneType错误。
5. 验证SQLAlchemy会话的扩展配置
确保数据库会话创建时,已经加载了SQLAlchemy-i18n的扩展:
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker engine = create_engine("postgresql://user:pass@localhost/db") Session = sessionmaker(bind=engine)
SQLAlchemy-i18n会自动绑定到会话,但如果会话创建前未执行make_translatable,扩展不会生效。
内容的提问来源于stack exchange,提问作者Cm1602
相关产品推荐
相关产品推荐

