freelawproject / courtlistener

A fully-searchable and accessible archive of court data including growing repositories of opinions, oral arguments, judges, judicial financial records, and federal filings.
https://www.courtlistener.com
Other
544 stars 150 forks source link

Upgrade to pghistory 3.0 #4431

Closed mlissner closed 3 weeks ago

mlissner commented 1 month ago

There's a new version of pghistory that seems to reply to some concerns we had, and which seems to make our lives a lot easier. See:

https://github.com/Opus10/django-pghistory/issues/78#issuecomment-2325132854

And:

https://github.com/Opus10/django-pghistory/issues/83#issuecomment-2325129154

Pretty cool.

We should go ahead and do the upgrade and figure out how to use these features and others that seem to be landing in v3.

@flooie, Kevin was the master of pghistory. Can you slide this into his priority list somewhere?

wesleykendall commented 1 month ago

Let me know if you have any issues or if your use case is still awkward with the latest version

wesleykendall commented 1 month ago

The custom trackers docs and the section following are a bit sparse on examples, but here's a snippet to help:

import pghistory

@pghistory.track(
    pghistory.UpdateEvent(
        "email_changed",
        row=pghistory.Old,
        condition=pghistory.AnyChange("email")
    ),
    model_name="UserEmailHistory"
)
class MyUser(models.Model):
    username = models.CharField(max_length=128)
    email = models.EmailField()
    address = models.TextField()

Above, UpdateEvent is snapshotting OLD whenever there is any change to email. For update triggers, the conditional utilities like pghistory.AnyChange above can help reduce the boilerplate for some expressions.

When calling pghistory.track this way, it overrides the default trackers, which are just pghistory.InsertEvent(), pghistory.UpdateEvent().

If you want to override the global default configuration, you can set this setting:

import pghistory

PGHISTORY_DEFAULT_TRACKERS = (pghistory.UpdateEvent(row=pghistory.Old), pghistory.DeleteEvent())

In the above, we're only tracking updates and deletes, preserving the OLD row (I believe this maps to your original issue of how you wanted to track changes).

With this change, any default invocation of @pghistory.track() will use those trackers by default. Could help save on a lot of boilerplate if you're doing this in many places (perhaps I could check out your codebase at some point and see)