I see. I think I can do okay without UserKeyword.user, as you suggested.
Seems to work.
Though is it really necessary to define user_keywords relationship both on
user and super_user? It seems to be working with only defining it in user.
On Sunday, August 21, 2016 at 9:33:01 PM UTC+3, Mike Bayer wrote:
>
>
>
> On 08/21/2016 10:22 AM, Tom Kedem wrote:
> > 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.
>
>
> This is the error:
>
> sqlalchemy.orm.exc.FlushError: Attempting to flush an item of type
> <class '__main__.SuperUser'> as a member of collection
> "UserKeyword.user". Expected an object of type <class '__main__.User'>
> or a polymorphic subclass of this type. If <class '__main__.SuperUser'>
> is a subclass of <class '__main__.User'>, configure mapper
> "Mapper|User|user" to load this subtype polymorphically, or set
> enable_typechecks=False to allow any subtype to be accepted for flush.
>
>
> this error is more of a warning to stop you from proceeding as though
> things are "normal" - it has no problem persisting a SuperUser here,
> however when you go later to load some_user_keyword.user, it will query
> the user table only, and return a User object, not a SuperUser. It's
> not possible for it to detect a SuperUser because you aren't using a
> discriminator.
>
> Your options are:
>
> 1. make two separate user_keywords relationships, and get rid of
> UserKeyword.user totally, since it can't be relied upon to load a
> SuperUser.
>
> 2. same thing, but keep UserKeyword.user and set the above-mentioned
> enable_typechecks=False on it. Still risky to call upon it because it
> can't load a SuperUser. see attached.
>
> Unfortunately, it does not seem to be possible to have a "user" and a
> separate "super_user" relationship on UserKeyword that share the same
> UserKeyword.user_id parameter, and they appear to conflict on flush.
>
> 3. Use polymorphic loading without a discriminator column, by using a
> CASE expression that checks for the super_user table being present in a
> row. This is a lot like what the concrete polymorphic loading does,
> though we don't have the declarative helpers for this pattern. Setting
> it up would be a little more manual and it means all queries for User,
> or at least the ones from UserKeyword.user if we made a special mapper
> just for this operation, would query an outer join against both tables.
> I can try to work this out if you are interested. But I don't think you
> even need to have UserKeyword.user here.
>
>
>
>
>
> >
> >
> > 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
> > <http://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>
> > > <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>
> > > <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:>
> <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
> > <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.