build a sqlalchemy history table for given prop
(
cls: declarative.DeclarativeMeta,
prop: T_PROPS,
schema: str = None)
| 296 | |
| 297 | |
| 298 | def build_history_table( |
| 299 | cls: declarative.DeclarativeMeta, |
| 300 | prop: T_PROPS, |
| 301 | schema: str = None) -> sa.Table: |
| 302 | """build a sqlalchemy history table for given prop""" |
| 303 | if isinstance(prop, orm.RelationshipProperty): |
| 304 | columns = [util.copy_column(column) for column in prop.local_columns] |
| 305 | else: |
| 306 | columns = [util.copy_column(column) for column in prop.columns] |
| 307 | |
| 308 | local_table = cls.__table__ |
| 309 | history_table_name = _generate_history_table_name(local_table, columns) |
| 310 | table_name = util.truncate_identifier(history_table_name) |
| 311 | # Build the foreign key(s), specifically adding an index since we may use |
| 312 | # a casted foreign key in our constraints. See _exclusion_in_uuid |
| 313 | entity_foreign_keys = list(util.foreign_key_to(local_table, index=True)) |
| 314 | entity_constraints = [ |
| 315 | _exclusion_in(fk.type, fk.key) |
| 316 | for fk in entity_foreign_keys |
| 317 | ] |
| 318 | |
| 319 | constraints = [ |
| 320 | sa.Index( |
| 321 | util.truncate_identifier('%s_effective_idx' % table_name), |
| 322 | 'effective', |
| 323 | postgresql_using='gist', |
| 324 | ), |
| 325 | sap.ExcludeConstraint( |
| 326 | *itertools.chain(entity_constraints, [('vclock', '&&')]), |
| 327 | name=util.truncate_identifier('%s_excl_vclock' % table_name), |
| 328 | ), |
| 329 | sap.ExcludeConstraint( |
| 330 | *itertools.chain(entity_constraints, [('effective', '&&')]), |
| 331 | name=util.truncate_identifier('%s_excl_effective' % table_name), |
| 332 | ), |
| 333 | ] |
| 334 | |
| 335 | return sa.Table( |
| 336 | table_name, |
| 337 | local_table.metadata, |
| 338 | sa.Column('id', |
| 339 | sap.UUID(as_uuid=True), |
| 340 | default=uuid.uuid4, |
| 341 | primary_key=True), |
| 342 | sa.Column('effective', |
| 343 | sap.TSTZRANGE, |
| 344 | default=util.effective_now, |
| 345 | nullable=False), |
| 346 | sa.Column('vclock', sap.INT4RANGE, nullable=False), |
| 347 | *itertools.chain(entity_foreign_keys, columns, constraints), |
| 348 | schema=schema or local_table.schema, |
| 349 | keep_existing=True, |
| 350 | ) # memoization ftw |