On Thu, Sep 4, 2014 at 3:30 PM, Michael Bayer <mike...@zzzcomputing.com>
wrote:

>
> On Sep 4, 2014, at 5:37 PM, Ken Lareau <klar...@tagged.com> wrote:
>
> So I have a few tables as follows (abbreviated for unnecessary columns):
>
> class Project(Base):
>     __tablename__ = 'projects'
>
>     id = Column(u'project_id', INTEGER(), primary_key=True)
>
>     applications = relationship(
>         'AppDefinition',
>         secondary=lambda: Base.metadata.tables['project_package'],
>         passive_deletes=True,
>         lazy=False,
>     )
>
>     package_definitions = relationship(
>         'PackageDefinition',
>         secondary=lambda: Base.metadata.tables['project_package'],
>         passive_deletes=True,
>     )
>
>
> class PackageDefinition(Base):
>     __tablename__ = 'package_definitions'
>
>     id = Column(u'pkg_def_id', INTEGER(), primary_key=True)
>
>     applications = relationship(
>         'AppDefinition',
>         secondary=lambda: Base.metadata.tables['project_package'],
>         passive_deletes=True,
>     )
>
>     projects = relationship(
>         'Project',
>         secondary=lambda: Base.metadata.tables['project_package'],
>         passive_deletes=True,
>     )
>
>
> class AppDefinition(Base):
>     __tablename__ = 'app_definitions'
>
>     id = Column(u'AppID', SMALLINT(display_width=2), primary_key=True)
>
>     package_definitions = relationship(
>         'PackageDefinition',
>         secondary=lambda: Base.metadata.tables['project_package'],
>         passive_deletes=True,
>     )
>
>     projects = relationship(
>         'Project',
>         secondary=lambda: Base.metadata.tables['project_package'],
>         passive_deletes=True,
>     )
>
>
> class ProjectPackage(Base):
>     __tablename__ = 'project_package'
>
>     project_id = Column(
>         INTEGER(),
>         ForeignKey('projects.project_id', ondelete='cascade'),
>         primary_key=True
>     )
>     pkg_def_id = Column(
>         INTEGER(),
>         ForeignKey('package_definitions.pkg_def_id', ondelete='cascade'),
>         primary_key=True
>     )
>     app_id = Column(
>         SMALLINT(display_width=6),
>         ForeignKey('app_definitions.AppID', ondelete='cascade'),
>         primary_key=True
>     )
>
>     app_definition = relationship('AppDefinition', uselist=False)
>     package_definition = relationship('PackageDefinition', uselist=False)
>     project = relationship('Project', uselist=False)
>
>
> this model has serious issues, though it can be made to hobble along with
> some small changes.  The “three way association table” is not a great
> pattern in the first place.  Additionally, using that same table as
> “secondary” in all those places is clearly the issue here, and they don’t
> even have back_populates between them, which are used in many-to-many in
> order to try avoid “double deleting”.   But that wouldn’t solve the issue
> here anyway.
>

As I feared, I figured this model would be frowned upon. :)  Note that this
model (or the underlying database)
is not set in stone; if you have suggestions on a better way to link the
three main tables, I would love to hear
it (and we did add back_populates (somehow missed them during the
restructuring of the models), but as
you said, didn't help in this case).


>
> In this case, you have mapped to the project_package table directly;
> you’re using the association object pattern.  The note at the end of
> http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#association-object
> applies here - you absolutely should have viewonly=True on all of those
> relationship() directives that refer to this association table as the
> “secondary” table.  The ORM otherwise has no way to know what changes
> should result in what deletions where.
>

Will add the 'viewonly' option as suggested and see if that helps, but as
mentioned above, if you can suggest
a better model for this case, please let me know!

-- 
- Ken Lareau

-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to