django-pghistory
django-pghistory copied to clipboard
Upgrading to version 2
django-pghistory
tracks history with triggers that are installed by django-pgtrigger
. django-pgtrigger
is now integrated with the migration system, so triggers will appear in migrations from now on.
Instructions for upgrading
After upgrading to version 2 of django-pghistory
, the majority of people can simply run python manage.py makemigrations
to make the migrations for the triggers. If, however, you are tracking third-party models, you will need to register trackers on proxy models. Otherwise trigger migrations will be created outside of your project.
Important - Please be sure you have django-pgtrigger>=4.5
installed, otherwise django-pghistory
might be susceptible to some migration-related bugs
For example, this is how you can track changes to Django's user model:
# Track the user model, excluding the password field
@pghistory.track(
pghistory.Snapshot('user.snapshot'),
exclude=['password'],
)
class UserProxy(User):
class Meta:
proxy = True
The same syntax is also used for default many-to-many "through" models. For example, this is how one tracks changes to group add/remove events on the user model:
from django.contrib.auth.models import User
import pghistory
# Track add and remove events to user groups
@pghistory.track(
pghistory.AfterInsert('group.add'),
pghistory.BeforeDelete('group.remove'),
obj_fk=None,
)
class UserGroups(User.groups.through):
class Meta:
proxy = True
Maintaining legacy behavior
If you want to disable django-pgtrigger
integration with migrations entirely, set settings.PGTRIGGER_MIGRATIONS
to False
. Setting this along with settings.PGTRIGGER_INSTALL_ON_MIGRATE
to True
will preserve the legacy behavior of how triggers were installed. It is not recommend to do this
Other changes
Along with this, there is no longer a dependency on django-pgconnection
. You no longer have to wrap settings.DATABASES
with django-pgconnection
after upgrading
Issues?
If you have any issues with the upgrade, please comment here and I will try to assist
Thanks for offering the documentation. I did NOT upgrade to version 2 ( currently on 1.5.0 with Django 3.2). However, the migration failed recently, perhaps it still pull the latest pgtrigger 4. Thanks again for providing PGTRIGGER_MIGRATIONS for backward compatibility before I migrate to v2.
ValueError: Could not automatically serialize Trigger <class 'pghistory.trigger.Event'> for migrations. Implement "get_init_vals()" on the trigger class. See the FAQ in the django-pgtrigger docs for more information.
@xjlin0 yea that error will happen if you remain on pghistory<2 and pull in an upgraded pgtrigger. As you mentioned, the PGTRIGGER_MIGRATIONS=False
should alleviate that issue if you want to get some of the latest bugfixes of pgtrigger and remain on pghistory<2 without using migrations to install triggers.
Thanks for reporting!
Arrh, I just found that running 1.5.1 with PGTRIGGER_MIGRATIONS=False
will get no errors but also no records in history table. Time to update....
@xjlin0 you need to set PGTRIGGER_MIGRATIONS to False and PGTRIGGER_INSTALL_ON_MIGRATE to True to preserve old behavior. My comment was missing a step
I'd still recommend upgrading to use the migration system, but the old behavior is there if you need it
Thanks, I can confirm the above combination of both PGTRIGGER_MIGRATIONS False + PGTRIGGER_INSTALL_ON_MIGRATE True in settings can restore pghistory version 1 behavior of storing events.
Now I've successfully upgraded to pghistory version 2, it's nice to see trigger additions in the migrations. Everything works beautifully, except I still have some difficulties to show certain django_celery_beat models in Django Admin UI. Also, if anyone happened to use shell_plus, you may notice the proxy model loading error message upon shell plus start up. To suppress such error messages, you can skip proxy model loading for shell plus by adding settings something like:
SHELL_PLUS_DONT_LOAD = [
'users.GroupProxy',
'users.PermissionProxy',
'users.UserGroupProxy',
'users.UserPermissionProxy',
]
@xjlin0 thanks for letting us know! What loading error messages do you receive for those proxy models? If it's an error related to pghistory I can open up an issue
Ha! proxy model loading error messages may not be related to pghistory, perhaps related to that Proxy model is still loaded by shell_plus by default. it's like:
$ python manage.py shell_plus
# Shell Plus Model Imports
Failed to import 'GroupProxy' from 'project.users.apps' reason: Module "project.users.apps" does not define a "GroupProxy" attribute/class
from django.contrib.auth.models import Group, Permission
.....
Regarding PeriodicTask & IntervalSchedule showing no events in Django Admin UI, I have no clues, since all other models shows events in Django Admin UI correctly with similar way.
from django_celery_beat.models import PeriodicTask
from django_celery_beat.admin import PeriodicTaskAdmin
admin.site.unregister(PeriodicTask)
@admin.register(PeriodicTask) # Somehow Admin UI shows no events
class PeriodicTaskAdmin(PeriodicTaskAdmin):
object_history_template = 'pghistory_template.html'
def history_view(self, request, object_id, extra_context=None): # same method from the doc
.....