18F / rdbms-subsetter

Generates a subset of a relational database that respects foreign key constraints
Creative Commons Zero v1.0 Universal
313 stars 30 forks source link

Event handling with blinker #33

Closed brki closed 8 years ago

brki commented 8 years ago

This will resolve #29, and is meant to replace pull request #30 , where the good suggestion was made to use blinker for handling signals.

Again, here's an example of how I'm using it:

from blinker import signal
import sqlalchemy as sa
import subsetter

# This signal handler is triggered by the rdbms-subsetter script;
# it is used here to ensure that when a row from a versioned
# table is added to the subset db, all past/future versions
# of that obect are also added.
row_added_signal = signal(subsetter.SIGNAL_ROW_ADDED)
@row_added_signal.connect
def row_added(source_db, source_row=None, target_db=None, target_table=None, prioritized=False):
    # Nothing to do unless this is a versioned table.
    if 'version_start_date' not in source_row:
        return

    # Add all previous / future versions.
    has_previous_versions = source_row.version_start_date != source_row.version_birth_date
    has_future_versions = source_row.version_end_date is not None and source_row.id != source_row.identity
    if has_previous_versions or has_future_versions:
    versions_select = sa.sql.select([target_table]).where(sa.and_(target_table.c.identity == source_row.identity, target_table.c.id != source_row.id))
    for version_row in source_db.conn.execute(versions_select):
        source_db.create_row_in(version_row, target_db, target_table)
brki commented 8 years ago

Note that merging this and #28 will cause a merge conflict. The correct merging of the conflicted version of subsetter.py can be seen here: https://github.com/brki/rdbms-subsetter/blob/ad22686a30dff1899f35756573180896f7308758/subsetter.py#L287-L297