[Python] SQLAlchemy_i18n creating translations causes errors

Discussão em 'Python' iniciado por Stack, Abril 29, 2025.

  1. Stack

    Stack Membro Participativo

    I have a strawberry graphql app that's using SQLAlchemy for models, and SQLAlchemy_i18n for internationalisation. I've followed the basic setup guide for i18n on the package docs but I just can't seem to get it working.

    I have a global locale set up in my init for the db session:

    # app/db/__init__.py
    import sqlalchemy_utils
    from sqlalchemy_i18n import make_translatable

    from app.locale import get_locale

    sqlalchemy_utils.i18n.get_locale = get_locale
    make_translatable(options={"locales": ["en", "fr"], "auto_create_locales": True})


    app.locale is just a file that overrides sqlalchemy_utils.i18n.get_locale = "en" for testing.

    I have a model set up as follows:

    from sqlalchemy import (
    Boolean,
    Column,
    Date,
    Float,
    ForeignKey,
    Integer,
    String,
    Table,
    Text,
    )

    from sqlalchemy.orm import relationship
    from sqlalchemy_i18n import Translatable, translation_base

    from app.db.session import Base

    class Category(Base, Translatable):
    __tablename__ = "category"
    __translatable__ = {'locales': ["en", "fr"]}
    category_id = Column(Integer, primary_key=True)
    uuid = Column(String, nullable=False)
    code = Column(String)
    locale = "en"

    class CategoryTranslation(translation_base(Category)):
    __tablename__ = "category_trans"
    category = Column(String, nullable=False)
    desc = Column(String, nullable=False)


    And I'm trying to run a graphql mutation that looks like this:

    import uuid
    import strawberry
    from strawberry.types import Info
    from app.db.session import get_db
    from app.models.models import Category, CategoryTranslation
    from app.types.types import Category as CategoryType

    @strawberry.input
    class CreateCategoryInput:
    category: str
    desc: str

    def create_category_resolver(
    data: CreateCategoryInput, info: Info, locale: str = "en"
    ) -> CategoryType:
    db_session = next(get_db())
    try:
    uuid_str = str(uuid.uuid4())
    new_category = Category(locale=locale, uuid=uuid_str, code=None)
    print(f"Locale for new category: {new_category.locale}")
    print(f"Valid locales: {new_category.__translatable__['manager'].option(new_category, 'locales')}")
    db_session.add(new_category)
    print("test123")
    db_session.flush()
    new_category.translations['en'] = CategoryTranslation(
    category=data.category,
    desc=data.desc,

    )
    print("Translations:", new_category.translations)


    db_session.flush()
    db_session.commit()


    return CategoryType(
    categoryId=new_category.category_id,
    uuid=new_category.uuid,
    code=new_category.code,
    category=new_category.translations[locale].category,
    desc=new_category.translations[locale].desc,
    )
    except Exception as e:
    db_session.rollback()
    print(f"Error creating category: {e}")
    raise e
    finally:
    db_session.close()


    The idea in the end is to grab the locale from the frontend but I'm hardcoding it in a few locations for debugging. As you can see I have a few test prints there, it never makes it to "testing123" which means it fails on adding the instance. I've tried doing translations first before adding to the session and that also fails. The locales print out as expected, "en" first, and ['en', 'fr'] on the second print.

    The error I'm getting is as follows:

    File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/sqlalchemy/orm/session.py", line 3481, in add
    self._save_or_update_state(state)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^
    File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/sqlalchemy/orm/session.py", line 3508, in _save_or_update_state
    for o, m, st_, dct_ in mapper.cascade_iterator(
    ~~~~~~~~~~~~~~~~~~~~~~~^
    "save-update", state, halt_on=self._contains_state
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ):
    ^
    File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/sqlalchemy/orm/mapper.py", line 3979, in cascade_iterator
    queue = deque(
    prop.cascade_iterator(
    ...<5 lines>...
    )
    )
    File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/sqlalchemy/orm/relationships.py", line 1524, in cascade_iterator
    tuples = state.manager[self.key].impl.get_all_pending(state, dict_)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    AttributeError: 'NoneType' object has no attribute 'get_all_pending'


    The docs I consulted on i18n are fairly slim https://sqlalchemy-i18n.readthedocs.io/en/latest/ so I'm finding it hard to figure out what's wrong here

    Continue reading...

Compartilhe esta Página