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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:05:07