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 <tomk...@gmail.com > > > <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 sqlalchemy+...@googlegroups.com > > <javascript:>. > > > To post to this group, send email to > > sqlal...@googlegroups.com <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 sqlalchemy+...@googlegroups.com <javascript:> > > > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:> > <javascript:>>. > > > To post to this group, send email to sqlal...@googlegroups.com > > <javascript:> > > > <mailto:sqlal...@googlegroups.com <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 sqlalchemy+...@googlegroups.com <javascript:> > > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:>>. > > To post to this group, send email to sqlal...@googlegroups.com > <javascript:> > > <mailto:sqlal...@googlegroups.com <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 sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.