maps properties to temporal models, builds a clock table, handles optional activity class for changes
(*track, mapper: orm.Mapper, activity_class=None,
schema=None, allow_persist_on_commit=False)
| 21 | |
| 22 | |
| 23 | def temporal_map(*track, mapper: orm.Mapper, activity_class=None, |
| 24 | schema=None, allow_persist_on_commit=False): |
| 25 | """ maps properties to temporal models, builds a clock table, handles optional activity class for changes """ |
| 26 | assert 'vclock' not in track |
| 27 | |
| 28 | cls = mapper.class_ |
| 29 | entity_table = mapper.local_table |
| 30 | # get things defined on Temporal: |
| 31 | tracked_props = frozenset( |
| 32 | mapper.get_property(prop) for prop in track |
| 33 | ) |
| 34 | # make sure all temporal properties have active_history (always loaded) |
| 35 | for prop in tracked_props: |
| 36 | getattr(cls, prop.key).impl.active_history = True |
| 37 | |
| 38 | schema = schema or entity_table.schema |
| 39 | |
| 40 | clock_table = build_clock_table( |
| 41 | entity_table, |
| 42 | entity_table.metadata, |
| 43 | schema, |
| 44 | activity_class, |
| 45 | ) |
| 46 | clock_properties = { |
| 47 | 'entity': orm.relationship( |
| 48 | lambda: cls, backref=orm.backref('clock', lazy='dynamic'), |
| 49 | ), |
| 50 | 'entity_first_tick': orm.relationship( |
| 51 | lambda: cls, |
| 52 | backref=orm.backref( |
| 53 | 'first_tick', |
| 54 | primaryjoin=sa.and_( |
| 55 | clock_table.join(entity_table).onclause, |
| 56 | clock_table.c.tick == 1, |
| 57 | ), |
| 58 | innerjoin=True, |
| 59 | uselist=False, # single record |
| 60 | viewonly=True, # view only |
| 61 | ), |
| 62 | ), |
| 63 | 'entity_latest_tick': orm.relationship( |
| 64 | lambda: cls, |
| 65 | backref=orm.backref( |
| 66 | 'latest_tick', |
| 67 | primaryjoin=sa.and_( |
| 68 | clock_table.join(entity_table).onclause, |
| 69 | entity_table.c.vclock == clock_table.c.tick, |
| 70 | ), |
| 71 | innerjoin=True, |
| 72 | uselist=False, # single record |
| 73 | viewonly=True, # view only |
| 74 | ), |
| 75 | ), |
| 76 | '__table__': clock_table, |
| 77 | } # used to construct a new clock model for this entity |
| 78 | |
| 79 | if activity_class: |
| 80 | # create a relationship to the activity from the clock model |
no test coverage detected