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.

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.


-- 
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