Wie man sqlmodel InvalidRequestError behebt: Mapper 'Mapper[...]' has no property '...'. If this property was indicated from other mappers or configure events, ensure registry.configure() has been called.

English Deutsch

Problem

Sie haben ein sqlmodel-Set von Modellen wie

sqlmodel_invalidrequest_example.py

class Offer(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    # ...

class Product(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    # ...
    offers: List[Offer] = Relationship(
        back_populates="products",
        link_model=ProductOfferLink
    )

class ProductOfferLink(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    product_id: int = Field(foreign_key="product.id")
    offer_id: int = Field(foreign_key="offer.id")

Aber wenn Sie versuchen, eines dieser Modelle zu erstellen, erhalten Sie einen Fehler wie

sqlalchemy_error_log.txt
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/state.py", line 566, in _initialize_instance
    manager.dispatch.init(self, args, kwargs)
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/event/attr.py", line 497, in __call__
    fn(*args, **kw)
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 4396, in _event_on_init
    instrumenting_mapper._check_configure()
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 2388, in _check_configure
    _configure_registries({self.registry}, cascade=True)
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 4204, in _configure_registries
    _do_configure_registries(registries, cascade)
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 4245, in _do_configure_registries
    mapper._post_configure_properties()
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 2405, in _post_configure_properties
    prop.init()
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/interfaces.py", line 584, in init
    self.do_init()
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/relationships.py", line 1647, in do_init
    self._generate_backref()
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/relationships.py", line 2133, in _generate_backref
    self._add_reverse_property(self.back_populates)
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/relationships.py", line 1578, in _add_reverse_property
    other = self.mapper.get_property(key, _configure_mappers=False)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/uli/.local/lib/python3.12/site-packages/sqlalchemy/orm/mapper.py", line 2511, in get_property
    raise sa_exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: Mapper 'Mapper[Offer(offer)]' has no property 'product'.  If this property was indicated from other mappers or configure events, ensure registry.configure() has been called.

Lösung

Das Problem hier ist, dass Sie in Product angegeben haben, dass es eine Beziehung zu Offer mit back_populates="products" hat, aber diese Spalte (products) existiert nicht in Offer.

Um dies zu beheben, müssen Sie sicherstellen, dass das back_populates-Argument in der Relationship auf den korrekten Spaltennamen im anderen Modell gesetzt ist, oder erstellen Sie es:

sqlmodel_relationship_fix.py

class Offer(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    # ...
    # Add this line to fix the issue
    products: List["Product"] = Relationship(
        back_populates="offers",
        link_model=ProductCategoryLink
    )

Die Spalte muss exakt so geschrieben werden wie im anderen Modell, also überprüfen Sie doppelt, ob das der Fall ist.

Alternativ können Sie das back_populates-Argument aus der Relationship entfernen, wenn Sie es nicht benötigen.


Check out similar posts by category: SQLModel, Python