It seems I confused "concrete" with "joined" inheritance.
What I want to achieve is *joined* inheritance. I've modified the code to
reflect that (just removed all concrete references).
According to the documentation relationships on joined inheritance are
inherited, but I still get an error saying it doesn't recognize super_user
as a child of user.
On Sunday, August 21, 2016 at 6:37:19 AM UTC+3, Mike Bayer wrote:
>
>
>
> On 08/20/2016 08:27 PM, Tom Kedem wrote:
> > I suppose I could have a discriminator value for "function type", but I
> > have no use for it now (so yeah, the base class is a single column one).
> >
> > It's a simplified model. The real use-case is as such - the base class
> > is "function" and the inheriting classes are all sorts of functions (all
> > concrete classes). They all have a collection of "arguments" (many to
> > many), which I define in the base class - since the "arguments" can only
> > point to a single table.
> >
> > Maybe it's not the best mapping, I'm open for suggestions. But is there
> > anything wrong in my configuration or understanding?
>
> Two things do not make sense, in terms of the use of ConcreteBase and
> "concrete=True".
>
> One is:
>
>
> id = Column(Integer, ForeignKey(User.id), primary_key=True)
>
> on SuperUser.
>
> The other is:
>
> class UserKeyword(Base):
> __tablename__ = 'user_keyword'
> user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
>
>
> both of these imply that the fields of a SuperUser object are stored in
> the "super_user" table *and* the "user" table.
>
> Also, when you say "I suppose I could have a discriminator..." in
> response to the question, "did you mean for this to be joined
> inheritance?", that suggests you might be under the impression that
> "don't have a discriminator" means you must use "concrete inheritance",
> which is not true. A "discriminator" is not necessary for any style
> of inheritance, as long as you don't need to load objects polymorphically.
>
> Same question as before, more specifically. When you load a row from
> "super_user" in order to get a SuperUser object, should the ORM also be
> loading a row from "user" that matches up to it? Or can you get every
> possible field in a SuperUser from the "super_user" table alone without
> ever looking at "user"? If the former, that would be joined
> inheritance. that's what this looks like.
>
>
>
>
>
>
>
>
>
> >
> > On Saturday, August 20, 2016 at 10:44:24 PM UTC+3, Mike Bayer wrote:
> >
> > This doesn't look like a concrete mapping, you have a foreign key
> > from SuperUser to User. Are you sure this isn't supposed to be an
> > ordinary joined inheritance model ?
> >
> > On Saturday, August 20, 2016, Tom Kedem <[email protected]
> > <javascript:>> wrote:
> >
> > I have the following setup (attached python file).
> > I'm using an inheritance hierarchy without a discriminator
> > field, deriving from AbstractBase.
> > I want to be able to use the "keywords" attribute in the
> > "SuperUser" class, and from the documentation I understand I
> > need to redefine it, however that doesn't seem to work.
> > I assume I could manually use a primary join there (as the error
> > indicates), but as I understand that's exactly what
> > "AbstractBase" class should handle...
> >
> > --
> > You received this message because you are subscribed to the
> > Google Groups "sqlalchemy" group.
> > To unsubscribe from this group and stop receiving emails from
> > it, send an email to [email protected]
> <javascript:>.
> > To post to this group, send email to [email protected]
> <javascript:>.
> > Visit this group at https://groups.google.com/group/sqlalchemy
> > <https://groups.google.com/group/sqlalchemy>.
> > For more options, visit https://groups.google.com/d/optout
> > <https://groups.google.com/d/optout>.
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "sqlalchemy" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> > an email to [email protected] <javascript:>
> > <mailto:[email protected] <javascript:>>.
> > To post to this group, send email to [email protected]
> <javascript:>
> > <mailto:[email protected] <javascript:>>.
> > Visit this group at https://groups.google.com/group/sqlalchemy.
> > For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import Column
from sqlalchemy import String
from sqlalchemy import create_engine
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
# Inheritance without discriminator
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
keywords = association_proxy('user_keywords', 'keyword')
__mapper_args__ = {'polymorphic_identity': 'user'}
class UserKeyword(Base):
__tablename__ = 'user_keyword'
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
keyword_id = Column(Integer, ForeignKey('keyword.id'), primary_key=True)
special_key = Column(String(50))
user = relationship(User, backref=backref("user_keywords", cascade="all, delete-orphan"))
keyword = relationship("Keyword")
def __init__(self, keyword=None, user=None, special_key=None):
self.user = user
self.keyword = keyword
self.special_key = special_key
class Keyword(Base):
__tablename__ = 'keyword'
id = Column(Integer, primary_key=True)
keyword = Column('keyword', String(64))
def __init__(self, keyword):
self.keyword = keyword
def __repr__(self):
return 'Keyword(%s)' % repr(self.keyword)
class SuperUser(User):
__tablename__ = 'super_user'
id = Column(Integer, ForeignKey(User.id), primary_key=True)
role = Column(String(64))
__mapper_args__ = {'polymorphic_identity': 'super_user'}
# ????
#user_keywords = relationship(UserKeyword)
#keywords = association_proxy('user_keywords', 'keyword')
engine = create_engine('sqlite:///:memory:', echo=False)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
user = SuperUser()
for kw in (Keyword('new_from_blammo'), Keyword('its_big')):
user.keywords.append(kw)
session.add(user)
session.commit()