On Jun 6, 2013, at 2:21 PM, Andy <[email protected]> wrote:
> I've written a handful of primaryjoin and secondaryjoin attributes on
> Relationships. This mechanism is flexible, but it's error-prone, and I think
> that, at least for all the cases I've personally encountered, there could be
> a better way. As an example, I have:
>
> thing = Table('thing', metadata,
> Column('thing_id', Integer, primary_key=True),
> Column('favorite_group_id', Integer),
> ForeignKeyConstraint(['thing_id', 'favorite_group_id'], ['rel.thing_id',
> 'rel.group_id'], use_alter=True, name='foobar'))
>
> group = Table('group', metadata,
> Column('group_id', Integer, primary_key=True))
>
> rel = Table('rel', metadata,
> Column('group_id', Integer, ForeignKey('group.group_id', primary_key=True),
> Column('thing_id', Integer, ForeignKey('thing.thing_id'), primary_key=True))
>
> IOW I have things and groups. The rel table is a many-to-many relation
> between things and groups. A thing also may have a favorite group; if so,
> there has to be a rel between that thing and its favorite group. I don't
> have a foreign key directly from favorite_group_id because the equivalent
> constraint is already implied by the existing foreign keys.
that's a fascinating FK setup, took me a few minute to understand what i was
looking at, but sure I see why it's that way.
>
> Everything is straightforward to map, except the favorite_group relation on
> thing -- there's no foreign key.
well there is, it's to the primary key of your "rel" table. If you were using
the association pattern, then (I'm pretty sure) this would all work out
naturally.
What you're doing here though is not mapping "rel" and then doing kind of an
artificial primaryjoin over to "group" directly. So this is exactly the
reason primaryjoin exists, when you want to map "around" the normal linkages
between tables.
> So I can set primary and primaryjoin, but here's a different suggestion:
>
> Add a couple of flags to ForeignKeyConstraint so that I can have three kinds
> of ForeignKeyConstraint:
OK you need to know that I really, really hate flags. While we have lots of
them, each one has arrived to the codebase in shame. Flags mean that the
normal construction of your objects is not good enough, you also have to deal
with a big panel of switches that do strange things. They make your API more
complicated and mysterious.
> ForeignKeyConstraint(['thing_id', 'favorite_group_id'], ['rel.thing_id',
> 'rel.group_id'], use_alter=True, use_for_mapper=False, name='foobar'),
so this flag, is the most evil of all - it's a flag that explicitly leaks an
ORM concept into the Core. I think we are very close to having no leakage of
explicit ORM concepts in the Core whatsoever at the moment (even in private
APIs), but its a big library so I might be wrong. But that's certainly a goal.
If we were to have hints that the ORM could understand inside of schema
objects, it would be through some agnostic system like ForeignKeyContraint(,
info={"orm": False}), or something like that (something better than that).
> ForeignKeyConstraint(['favorite_group_id'], ['group.group_id'],
> use_alter=True, emit_ddl=False, name='foobar'))
>
> And now the trivial mapper relations will all work with no fiddling.
This flag at least is Core only but still, if emit_ddl is False then why do we
need use_alter and name?
>
> Thoughts?
When a beginner comes to SQLAlchemy, and they want to make a custom join
condition - now there are two entirely different ways of doing it. Which one
should they use and why ? That's probably the biggest concern I have here.
Two ways to do something means you have to produce the rationale for when to
use each one.
Not only that, but we are now placing ORM-specific configuration into our Table
metadata. What's wrong with doing it in relationship()? Clearly, the way
primaryjoin works, in that it's an expression, is cumbersome. But that seems
like a much easier problem to solve, just by adding some extra sugar to
relationship itself? Like relationship("MyTable", primaryjoin=[("a", "b"),
("c", "d")]) ? How is that more "fiddling" than the other approach?
--
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 http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.