Manually unregistering/re-registering cascading relationships in the ORM

8 views
Skip to first unread message

Christopher Webber

unread,
Feb 14, 2013, 3:29:41 PM2/14/13
to sqlal...@googlegroups.com
Hello,

I'm with the GNU MediaGoblin project.  We're happily using SQLAlchemy,
but we're running into a problem that's making it impossible for us to
presently write unit tests for our plugins.

The problem is that we'd like to use SQLAlchemy's built-in cascading
deletion.  However, we have plugins.  Consider the following plugin,
which adds this table:


class VideoData(Base):
    __tablename__ = "video__mediadata"

    # The primary key *and* reference to the main media_entry
    media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
        primary_key=True)
    get_media_entry = relationship("MediaEntry",
        backref=backref(BACKREF_NAME, uselist=False,
                        cascade="all, delete-orphan"))

    width = Column(SmallInteger)
    height = Column(SmallInteger)


now consider that we are running two sets of tests, one with the
videodata plugin turned on, one without.  With the foreign key setup
above, if we do a MediaEntry().delete() and the plugin is *not* on,
thus the table *doesn't* exist, it tries passing SQL to delete data
from a table that doesn't exist at all.  As you can imagine, this
makes SQLAlchemy barf.

So, between our unit tests we need to register and unregister
relations between the tables depending on which plugins are loaded.
However, it looks like there is no builtin way to do this.  We tried
doing metadata.remove(VideoData.__table__), but that did not fix it.
Furthermore, we have no idea how one would add back a relation,
either!

Any ideas?

Thank you,
 - Christopher Allan Webber and the GNU MediaGoblin team

Michael Bayer

unread,
Feb 14, 2013, 3:40:07 PM2/14/13
to sqlal...@googlegroups.com
unfortunately, surgically removing elements of a mapping is not supported, the only option is to remove mappings entirely.

With declarative, removal of mappings is one area that becomes more inconvenient as you can't so easily re-map by just saying "mapper()" again.

My advise would be to unit test the VideoData plugin entirely separately from the main model, and apply it only to an ad-hoc series of mappings that ensures it's behavior is as expected (this can be done using an alternate Base, for example) - basically more of a true unit test rather than an integration test.

Other than that you'd need to find a way to entirely reload your declarative model in order to produce the class model and mappings again.


Christopher Webber

unread,
Feb 14, 2013, 10:58:25 PM2/14/13
to sqlal...@googlegroups.com
Ah, that's disappointing to hear.  But thanks for clarifying!
Reply all
Reply to author
Forward
0 new messages