Module
pghistory
pghistory.AllChange
module-attribute
If all supplied fields change, trigger the event.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*fields |
str
|
If all supplied fields change, trigger the event. If no fields are supplied, defaults to all tracked fields. |
required |
exclude |
List[str]
|
Fields to exclude. |
required |
exclude_auto |
bool
|
Exclude all |
required |
pghistory.AllDontChange
module-attribute
If all supplied fields don't change, trigger the event.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*fields |
str
|
If all supplied fields don't change, trigger the event. If no fields are supplied, defaults to all tracked fields. |
required |
exclude |
List[str]
|
Fields to exclude. |
required |
exclude_auto |
bool
|
Exclude all |
required |
pghistory.AnyChange
module-attribute
If any supplied fields change, trigger the event.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*fields |
str
|
If any supplied fields change, trigger the event. If no fields are supplied, defaults to all tracked fields. |
required |
exclude |
List[str]
|
Fields to exclude. |
required |
exclude_auto |
bool
|
Exclude all |
required |
pghistory.AnyDontChange
module-attribute
If any supplied fields don't change, trigger the event.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*fields |
str
|
If any supplied fields don't change, trigger the event. If no fields are supplied, defaults to all tracked fields. |
required |
exclude |
List[str]
|
Fields to exclude. |
required |
exclude_auto |
bool
|
Exclude all |
required |
pghistory.Condition
module-attribute
For specifying free-form SQL in the condition of a trigger.
pghistory.DEFAULT
module-attribute
For setting a configuration value back to its default value
pghistory.Delete
module-attribute
For specifying DELETE
as the trigger operation.
pghistory.F
module-attribute
Similar to Django's F
object, allows referencing the old and new
rows in a trigger condition.
pghistory.Insert
module-attribute
For specifying INSERT
as the trigger operation.
pghistory.New
module-attribute
For storing the trigger's "NEW" row in a pghistory.RowEvent
pghistory.Old
module-attribute
For storing the trigger's "OLD" row in a pghistory.RowEvent
pghistory.Q
module-attribute
Similar to Django's Q
object, allows building filter clauses based on
the old and new rows in a trigger condition.
pghistory.Update
module-attribute
For specifying UPDATE
as the trigger operation.
pghistory.ContextForeignKey
ContextForeignKey(
*,
null: bool = True,
related_query_name: str = constants.DEFAULT,
**kwargs: Any
)
Bases: ForeignKey
Configuration for the pgh_context
field when a foreign key is used.
Overrides null to True
.
Attributes:
Name | Type | Description |
---|---|---|
null |
bool, default=True
|
True if nullable context is allowed |
related_query_name |
str
|
The related_query_name to use |
Source code in pghistory/config.py
pghistory.ContextJSONField
Bases: Field
Configuration for the pgh_context
field when denormalized context is used.
Attributes:
Name | Type | Description |
---|---|---|
null |
bool, default=True
|
True if nullable context is allowed |
Source code in pghistory/config.py
pghistory.ContextUUIDField
Bases: Field
Configuration for the pgh_context_id
field when denormalized context is used.
Attributes:
Name | Type | Description |
---|---|---|
null |
bool, default=True
|
True if nullable context is allowed |
Source code in pghistory/config.py
pghistory.DeleteEvent
DeleteEvent(
label: str = None,
*,
condition: Union[pgtrigger.Condition, None] = constants.UNSET,
operation: pgtrigger.Operation = None,
row: str = None,
trigger_name: str = None
)
Bases: RowEvent
Creates events based on deletes to a model
The default label used is "delete".
Source code in pghistory/core.py
pghistory.Field
Field(
*,
primary_key: bool = constants.UNSET,
unique: bool = constants.UNSET,
blank: bool = constants.UNSET,
null: bool = constants.UNSET,
db_index: bool = constants.UNSET,
editable: bool = constants.UNSET,
unique_for_date: bool = constants.UNSET,
unique_for_month: bool = constants.UNSET,
unique_for_year: bool = constants.UNSET
)
Configuration for fields.
The default values for the attributes ensure that event models don't have unnecessary uniqueness constraints carried over from the tracked model.
Attributes:
Name | Type | Description |
---|---|---|
primary_key |
bool, default=False
|
True if a primary key |
unique |
bool, default=False
|
True if unique |
blank |
bool
|
True if blank |
null |
bool
|
True if null |
db_index |
bool
|
True if indexed |
editable |
bool
|
True if editable |
unique_for_date |
bool
|
True if unique for date |
unique_for_month |
bool
|
True if unique for the month |
unique_for_year |
bool
|
True if unique for the year |
Source code in pghistory/config.py
pghistory.ForeignKey
ForeignKey(
*,
on_delete: Any = constants.UNSET,
db_constraint: bool = constants.UNSET,
**kwargs: Any
)
Bases: RelatedField
Configuration for foreign keys.
Arguments for RelatedField
and Field
can also be supplied.
Note that db_index is overridden to True
for all foreign keys
Attributes:
Name | Type | Description |
---|---|---|
on_delete |
default=models.DO_NOTHING
|
Django's on_delete property |
db_constraint |
bool, default=False
|
True to use a datbase constraint for the foreign key |
Source code in pghistory/config.py
pghistory.InsertEvent
InsertEvent(
label: str = None,
*,
condition: Union[pgtrigger.Condition, None] = constants.UNSET,
operation: pgtrigger.Operation = None,
row: str = None,
trigger_name: str = None
)
Bases: RowEvent
Creates events based on inserts to a model
The default label used is "insert".
Source code in pghistory/core.py
pghistory.ManualEvent
pghistory.ObjForeignKey
ObjForeignKey(
*,
related_name: str = constants.DEFAULT,
related_query_name: str = constants.DEFAULT,
**kwargs
)
Bases: ForeignKey
Configuration for the pgh_obj
field
Attributes:
Name | Type | Description |
---|---|---|
related_name |
str
|
The related_name to use |
related_query_name |
str
|
The related_query_name to use |
Source code in pghistory/config.py
pghistory.RelatedField
RelatedField(
*,
related_name: str = constants.UNSET,
related_query_name: str = constants.UNSET,
**kwargs: Any
)
Bases: Field
Configuration for related fields.
By default, related names are stripped to avoid unnecessary clashes.
Note that all arguments from Field
can also be supplied.
Attributes:
Name | Type | Description |
---|---|---|
related_name |
str, default="+"
|
The related_name to use |
related_query_name |
str, default="+"
|
The related_query_name to use |
Source code in pghistory/config.py
pghistory.RowEvent
RowEvent(
label: str = None,
*,
condition: Union[pgtrigger.Condition, None] = constants.UNSET,
operation: pgtrigger.Operation = None,
row: str = None,
trigger_name: str = None
)
Bases: Tracker
For tracking an event automatically based on row-level changes.
Source code in pghistory/core.py
pghistory.Tracker
For tracking an event when a condition happens on a model.
Source code in pghistory/core.py
pghistory_setup
Registers the tracker for the event model and calls user-defined setup
Source code in pghistory/core.py
pghistory.UpdateEvent
UpdateEvent(
label: str = None,
*,
condition: Union[pgtrigger.Condition, None] = constants.UNSET,
operation: pgtrigger.Operation = None,
row: str = None,
trigger_name: str = None
)
Bases: RowEvent
Creates events based on updates to a model.
By default,
- The label used is "update".
- Attributes from the "new" row of the update are stored.
- It only fires when fields of the event model are changed.
All of this behavior can be overridden by supplying a label, a condition, or the row to snapshot.
Source code in pghistory/core.py
pghistory.context
Bases: ContextDecorator
A context manager that groups changes under the same context and adds additional metadata about the event.
Context is added as variables at the beginning of every SQL statement. By default, all variables are localized to the transaction (i.e SET LOCAL), meaning they will only persist for the statement/transaction and not across the session.
Once any code has entered pghistory.context, all subsequent entrances of pghistory.context will be grouped under the same context until the top-most parent exits.
To add context only if a parent has already entered pghistory.context, one can call pghistory.context as a function without entering it. The metadata set in the function call will be part of the context if pghistory.context has previously been entered. Otherwise it will be ignored.
Attributes:
Name | Type | Description |
---|---|---|
**metadata |
Metadata that should be attached to the tracking context |
Example
Here we track a "key" with a value of "value":
with pghistory.context(key='value'):
# Do things..
# All tracked events will have the same `pgh_context`
# foreign key, and the context object will include
# {'key': 'value'} in its metadata.
# Nesting the tracker adds additional metadata to the current
# context
# Add metadata if a parent piece of code has already entered
# pghistory.context
pghistory.context(key='value')
Note
Context tracking is compatible for most scenarios, but it currently does not work for named cursors. Django uses named cursors for the .iterator() operator, which has no effect on history tracking. However, there may be other usages of named cursors in Django where history context is ignored.
Source code in pghistory/runtime.py
pghistory.ProxyField
Proxies a JSON field from a model and adds it as a field in the queryset.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
proxy |
str
|
The value to proxy, e.g. "user__email" |
required |
field |
Type[Field]
|
The field that will be used to cast the resulting value |
required |
Source code in pghistory/core.py
pghistory.create_event
Manually create a event for an object.
Events are automatically linked with any context being tracked via pghistory.context.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
obj |
Model
|
An instance of a model. |
required |
label |
str
|
The event label. |
required |
using |
str
|
The database |
'default'
|
Raises:
Type | Description |
---|---|
ValueError
|
If the event label has not been registered for the model. |
Returns:
Type | Description |
---|---|
Model
|
The created event model object |
Source code in pghistory/core.py
pghistory.create_event_model
create_event_model(
tracked_model: Type[models.Model],
*trackers: Tracker,
fields: Union[List[str], None] = None,
exclude: Union[List[str], None] = None,
obj_field: ObjForeignKey = constants.UNSET,
context_field: Union[ContextForeignKey, ContextJSONField] = constants.UNSET,
context_id_field: ContextUUIDField = constants.UNSET,
append_only: bool = constants.UNSET,
model_name: Union[str, None] = None,
app_label: Union[str, None] = None,
base_model: Type[models.Model] = None,
attrs: Dict[str, Any] = None,
meta: Dict[str, Any] = None,
abstract: bool = True
) -> Type[models.Model]
Create an event model.
Instead of using pghistory.track, which dynamically generates an event model, one can instead construct a event model themselves, which will also set up event tracking for the tracked model.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
tracked_model |
Type[Model]
|
The model that is being tracked. |
required |
*trackers |
Tracker
|
The event trackers. When using any tracker that inherits
pghistory.RowEvent, such as pghistory.InsertEvent, a
Postgres trigger will be installed that automatically stores the event
into the generated event model. Trackers that do not inherit
pghistory.RowEvent must be manually created. If no events are
supplied, defaults to |
()
|
fields |
Union[List[str], None]
|
The list of fields to snapshot when the event takes place. When
no fields are provided, the entire model is snapshot when the event
happens. Note that snapshotting of the OLD or NEW row is configured
by the |
None
|
exclude |
Union[List[str], None]
|
Instead of providing a list of fields to snapshot, a user can instead provide a list of fields to not snapshot. |
None
|
obj_field |
ObjForeignKey
|
The foreign key field configuration that references the tracked object.
Defaults to an unconstrained non-nullable foreign key. Use |
UNSET
|
context_field |
Union[ContextForeignKey, ContextJSONField]
|
The context field configuration. Defaults to a nullable
unconstrained foreign key. Use |
UNSET
|
context_id_field |
ContextUUIDField
|
The context ID field configuration when using a ContextJSONField
for the context_field. When using a denormalized context field, the ID
field is used to track the UUID of the context. Use |
UNSET
|
append_only |
bool
|
True if the event model is protected against updates and deletes. |
UNSET
|
model_name |
Union[str, None]
|
Use a custom model name when the event model is generated. Otherwise a default name based on the tracked model and fields will be created. |
None
|
app_label |
Union[str, None]
|
The app_label for the generated event model. Defaults to the app_label of the tracked model. Note, when tracking a Django model (User) or a model of a third-party app, one must manually specify the app_label of an internal app to use so that migrations work properly. |
None
|
base_model |
Type[Model]
|
The base model for the event model. Must inherit pghistory.models.Event. |
None
|
attrs |
Dict[str, Any]
|
Additional attributes to add to the event model |
None
|
meta |
Dict[str, Any]
|
Additional attributes to add to the Meta class of the event model. |
None
|
abstract |
bool
|
|
True
|
Returns:
Type | Description |
---|---|
Type[Model]
|
The event model class. |
Example
Create a custom event model:
class MyEventModel(create_event_model(
TrackedModel,
pghistory.InsertEvent(),
)):
# Add custom indices or change default field declarations...
Source code in pghistory/core.py
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
|
pghistory.track
track(
*trackers: Tracker,
fields: Union[List[str], None] = None,
exclude: Union[List[str], None] = None,
obj_field: ObjForeignKey = constants.UNSET,
context_field: Union[ContextForeignKey, ContextJSONField] = constants.UNSET,
context_id_field: ContextUUIDField = constants.UNSET,
append_only: bool = constants.UNSET,
model_name: Union[str, None] = None,
app_label: Union[str, None] = None,
base_model: Type[models.Model] = None,
attrs: Dict[str, Any] = None,
meta: Dict[str, Any] = None
)
A decorator for tracking events for a model.
When using this decorator, an event model is dynamically generated
that snapshots the entire model or supplied fields of the model
based on the events
supplied. The snapshot is accompanied with
the label that identifies the event.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*trackers |
Tracker
|
The event trackers. When using any tracker that inherits
pghistory.RowEvent, such as pghistory.InsertEvent, a
Postgres trigger will be installed that automatically stores the event
into the generated event model. Trackers that do not inherit
pghistory.RowEvent must be manually created. If no events are
supplied, defaults to |
()
|
fields |
Union[List[str], None]
|
The list of fields to snapshot when the event takes place. When no fields
are provided, the entire model is snapshot when the event happens. Note that
snapshotting of the OLD or NEW row is configured by the |
None
|
exclude |
Union[List[str], None]
|
Instead of providing a list of fields to snapshot, a user can instead provide a list of fields to not snapshot. |
None
|
obj_field |
ObjForeignKey
|
The foreign key field configuration that references the tracked object.
Defaults to an unconstrained non-nullable foreign key. Use |
UNSET
|
context_field |
Union[ContextForeignKey, ContextJSONField]
|
The context field configuration. Defaults to a nullable unconstrained
foreign key. Use |
UNSET
|
context_id_field |
ContextUUIDField
|
The context ID field configuration when using a ContextJSONField for
the context_field. When using a denormalized context field, the ID field is used to
track the UUID of the context. Use |
UNSET
|
append_only |
bool
|
True if the event model is protected against updates and deletes. |
UNSET
|
model_name |
Union[str, None]
|
Use a custom model name when the event model is generated. Otherwise a default name based on the tracked model and fields will be created. |
None
|
app_label |
Union[str, None]
|
The app_label for the generated event model. Defaults to the app_label of the tracked model. Note, when tracking a Django model (User) or a model of a third-party app, one must manually specify the app_label of an internal app to use so that migrations work properly. |
None
|
base_model |
Type[Model]
|
The base model for the event model. Must inherit |
None
|
attrs |
Dict[str, Any]
|
Additional attributes to add to the event model |
None
|
meta |
Dict[str, Any]
|
Additional attributes to add to the Meta class of the event model. |
None
|
Source code in pghistory/core.py
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
|
pghistory.admin
pghistory.admin.EventModelAdmin
Bases: BaseEventAdmin
The base admin for event models
pghistory.admin.EventsAdmin
Bases: BaseEventAdmin
The admin for showing events across all event models
pghistory.middleware
pghistory.middleware.WSGIRequest
Bases: WSGIRequest
Although Django's auth middleware sets the user in middleware, apps like django-rest-framework set the user in the view layer. This creates issues for pghistory tracking since the context needs to be set before DB operations happen.
This special WSGIRequest updates pghistory context when the request.user attribute is updated.
pghistory.middleware.HistoryMiddleware
Annotates the user/url in the pghistory context.
Source code in pghistory/middleware.py
pghistory.models
pghistory.models.Context
Bases: Model
install_pgh_attach_context_func
classmethod
Installs a custom store procedure for upserting context for historical events. The upsert is aware of when tracking is enabled in the app (i.e. using pghistory.context())
This stored procedure is automatically installed in pghistory migration 0004.
Source code in pghistory/models.py
pghistory.models.Event
Bases: Model
An abstract model for base elements of a event
check
classmethod
Allow proxy models to inherit this model and define their own fields that are dynamically pulled from context
Source code in pghistory/models.py
pghistory_setup
classmethod
Called when the class is prepared (see apps.py) to finalize setup of the model and register triggers
Source code in pghistory/models.py
revert
Reverts the tracked model based on the event fields.
Raises a RuntimeError if the event model doesn't track all fields
Source code in pghistory/models.py
pghistory.models.EventQuery
Bases: Query
A query over an event CTE when proxy fields are used
get_compiler
Overrides the Query method get_compiler in order to return an EventQueryCompiler.
Source code in pghistory/models.py
pghistory.models.EventQueryCompiler
Bases: SQLCompiler
as_sql
If there are proxied fields on the event model, return a select from a CTE. Otherwise don't do anything special
Source code in pghistory/models.py
pghistory.models.EventQuerySet
pghistory.models.Events
Bases: Model
A proxy model for aggregating events together across tables and rendering diffs
check
classmethod
Allow proxy models to inherit this model and define their own fields that are dynamically pulled from context
Source code in pghistory/models.py
pghistory.models.EventsQuery
pghistory.models.EventsQueryCompiler
Bases: SQLCompiler
pghistory.models.EventsQuerySet
Bases: QuerySet
QuerySet with support for Common Table Expressions
Source code in pghistory/models.py
across
Aggregates events across the provided event models
references
Query any rows that reference the objs.
If, for example, a foreign key or pgh_obj field points to the object, it will be aggregated.
Source code in pghistory/models.py
tracks
Query any rows with pgh_obj equal to the objs.
Source code in pghistory/models.py
pghistory.models.MiddlewareEvents
Bases: Events
A proxy model for aggregating events. Includes additional fields that are captured by the pghistory middleware
pghistory.models.NoObjectsManager
Bases: Manager
Django's dumpdata and other commands will not work with Events models by default because of how they aggregate multiple tables based on objects.
We use this as the default manager for aggregate events so that dumpdata and other management commands still work with these models
pghistory.models.PghEventModel
A descriptor for accessing the pgh_event_model field on a tracked model