Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declarative backref rels not filtering by polymorphic identity #492

Closed
revmischa opened this issue Apr 5, 2017 · 6 comments
Closed

Declarative backref rels not filtering by polymorphic identity #492

revmischa opened this issue Apr 5, 2017 · 6 comments
Milestone

Comments

@revmischa
Copy link

More info here:
https://bitbucket.org/zzzeek/sqlalchemy/issues/3960/declarative-backref-not-filtering-by

"the issue is somewhere in db.Model where their declarative base is interfering with declarative being able to set the "single inheritance" flag on the Event1 mapper."

@zzzeek
Copy link

zzzeek commented Apr 5, 2017

likely because tablename is set to non-None in all cases now: https://github.com/mitsuhiko/flask-sqlalchemy/blob/master/flask_sqlalchemy/__init__.py#L641 that should be None to indicate single inheritance.

@revmischa
Copy link
Author

@zzzeek it should be unset on the "base" classes, but set on the "child" classes? to the same thing?

@zzzeek
Copy link

zzzeek commented Apr 6, 2017

whichever class should have its own table gets tablename, whichever subclass that's single inh either should not have tablename at all (declarative looks in cls.dict to check that the attribute is local to a certain class) or it should return None - declarative then sets that mapper as single=True.

Basically the way db.Model here wants to do tablename, if it has that feature then you need to set tablename = None on your model.

@davidism
Copy link
Member

davidism commented Apr 6, 2017

I'm working on fixing the tablename logic, I'll keep this example in mind.

@davidism davidism modified the milestone: 2.2.1 Jun 8, 2017
@mark-anders
Copy link

Btw, the title of the bug is incorrect: it doesn't really involve relationships at all. It is that queries that specify a subclass do not emit a where clause when using polymorphic identity in single table, so effectively, the type is ignored.

Here's an example:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
app.config['SQLALCHEMY_ECHO'] = True

class Group(db.Model):
    __tablename__ = 'groups'

    group_id = Column(Integer, primary_key=True)
    name = Column(String)
    type = Column(String)

    __mapper_args__ = {
        'polymorphic_on': type,
        'polymorphic_identity': "group",
    }

    def __init__(self, name):
        self.name = name

class OwnerGroup(Group):
    # __tablename__ = None

    __mapper_args__ = {
        'polymorphic_identity': "owner"
    }


class SharedGroup(Group):
    # __tablename__ = None
    __mapper_args__ = {
        'polymorphic_identity': "shared"
    }

db.drop_all()
db.create_all()
session = db.session

o1 = OwnerGroup("#1 owner")
o2 = OwnerGroup("#2 owner")
s = SharedGroup("Shared")
session.add_all([o1,o2,s])
session.commit()
q = session.query(SharedGroup)
print(q)
found = q.all()
assert len(found) == 1, "Found too many SharedGroups"

Based on the hint from @zzzeek , if you uncomment the __tablename__ = None, it works.

This seems to be a pretty serious bug. Hope it gets fixed soon.

@davidism
Copy link
Member

Duplicate of #478. Should be covered by #541, which also adds a test that the query contains the polymorphic condition.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

4 participants