question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Many-to-Many relationships broken on SQLAlchemy>1.3.5

See original GitHub issue

Take the following model:

entry_tags_table = db.Table(
    "entry_tags",
    db.Model.metadata,
    db.Column("entry_id", db.Integer, db.ForeignKey("entry.id")),
    db.Column("tag_id", db.Integer, db.ForeignKey("tag.id")),
)
class Entry(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    tags = db.relationship("Tag", secondary=entry_tags_table)

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, nullable=False)
    entries = db.relationship("Entry", secondary=entry_tags_table)

[...]
class DefaultView(sqla.ModelView):
    column_searchable_list = [
        "title",
        "tags.name",
    ]

admin = admin.Admin(app, name='Test', template_mode='bootstrap4', index_view=DefaultView(Entry, db.session))

This will throw an error on SQLALchemy 1.4.x

/home/me/.virtualenvs/vp/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py:3435: SAWarning:
relationship 'Tag.entries' will copy column tag.id to column entry_tags.tag_id,
which conflicts with relationship(s): 'Entry.tags' (copies tag.id to entry_tags.tag_id).
If this is not the intention, consider if these relationships should be linked with back_populates,
or if viewonly=True should be applied to one or more if they are read-only.
For the less common case that foreign key constraints are partially overlapping,
the orm.foreign() annotation can be used to isolate the columns that should be written towards.
The 'overlaps' parameter may be used to remove this warning.

Adding back_populates or backrefs as suggested by the error message and as documented in Basic Relationship Patterns like this:

[...]
    entries = db.relationship(Entry, secondary=entry_tags_table, back_populates="tags")
[...]
    tags = db.relationship(Tag, secondary=entry_tags_table, back_populates="entries")

results in a new error:

Traceback (most recent call last):
  File "/home/me/data/sixfive/main.py", line 24, in <module>
    from admin import admin
  File "/home/me/data/sixfive/admin/__init__.py", line 1, in <module>
    from .view import admin
  File "/home/me/data/sixfive/admin/view.py", line 727, in <module>
    index_view=DefaultView(Entry, db.session, url="/admin"),
  File "/home/me/data/sixfive/admin/view.py", line 45, in __init__
    super(DefaultView, self).__init__(model, session, *args, **kwargs)
  File "/home/me/.virtualenvs/vp/lib/python3.9/site-packages/flask_admin/contrib/sqla/view.py", line 327, in __init__
    super(ModelView, self).__init__(model, name, category, endpoint, url, static_folder,
  File "/home/me/.virtualenvs/vp/lib/python3.9/site-packages/flask_admin/model/base.py", line 818, in __init__
    self._refresh_cache()
  File "/home/me/.virtualenvs/vp/lib/python3.9/site-packages/flask_admin/model/base.py", line 913, in _refresh_cache
    self._search_supported = self.init_search()
  File "/home/me/.virtualenvs/vp/lib/python3.9/site-packages/flask_admin/contrib/sqla/view.py", line 581, in init_search
    if tools.is_hybrid_property(self.model, name):
  File "/home/me/.virtualenvs/vp/lib/python3.9/site-packages/flask_admin/contrib/sqla/tools.py", line 215, in is_hybrid_property
    return last_name in get_hybrid_properties(last_model)
  File "/home/me/.virtualenvs/vp/lib/python3.9/site-packages/flask_admin/contrib/sqla/tools.py", line 195, in get_hybrid_properties
    for key, prop in inspect(model).all_orm_descriptors.items()
  File "/home/me/.virtualenvs/vp/lib/python3.9/site-packages/sqlalchemy/inspection.py", line 71, in inspect
    raise exc.NoInspectionAvailable(
sqlalchemy.exc.NoInspectionAvailable: No inspection system is available for object of type <class 'str'>
make: *** [Makefile:22: runserver] Error 1

The call to inspect() fails at is_hybrid_property() for the attr_name tags.name


Link to gist for reproducing: app.py

Library versions:

Flask-Admin      1.5.7
Flask-SQLAlchemy 2.5.1
SQLAlchemy       1.4.2

Possibly related:

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
alexa-infracommented, Mar 23, 2021

is_hybrid_property has been fixed recently in #2098

0reactions
ersanjay5991commented, Jul 28, 2022

If this is not the intention, consider if these relationships should be linked with back_populates, flask sqlalchemy

I change to model relation

users = db.relationship('User', secondary=association_table,back_populates="events")

Read more comments on GitHub >

github_iconTop Results From Across the Web

Many to one relationships within table in SqlAlchemy
Following Many to One relationship with SQLAlchemy in the same table I found a way to make that a 1 to many relationship....
Read more >
Configuring how Relationship Joins
One of the most common situations to deal with is when there are more than one foreign key path between two tables. Consider...
Read more >
Configuring Relationships — SQLAlchemy 1.3 Documentation
Evaluation of relationship arguments; Configuring Many-to-Many Relationships ... Declarative system interacts with SQLAlchemy ORM relationship constructs.
Read more >
1.3 Changelog — SQLAlchemy 2.0 Documentation
Fixed bug where a many-to-one relationship that specified uselist=True would fail to update correctly during a primary key change where a related column...
Read more >
Working with Engines and Connections — SQLAlchemy 1.3 ...
The Engine is not synonymous to the DBAPI connect function, which represents just one connection resource - the Engine is most efficient when...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found