Skip to content

Commit

Permalink
Fix db_column not being passed through on AutoFields (#168)
Browse files Browse the repository at this point in the history
* Pass db_column through on tracked AutoFields

* Don't pass db_column through unless it is different

* Add tests for db_column

* Add missing migration for tests

* Add clarification for db_column
  • Loading branch information
pmdevita authored Sep 28, 2024
1 parent 6e8840c commit 58a5513
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 2 deletions.
8 changes: 6 additions & 2 deletions pghistory/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,14 @@ def _generate_history_field(tracked_model, field):
"""
field = tracked_model._meta.get_field(field)

# db_column is always a value even if the user didn't set it, so we
# need to double-check that it's different before we pass it through
db_column = field.db_column if field.db_column != field.name else None

if isinstance(field, models.BigAutoField):
return models.BigIntegerField()
return models.BigIntegerField(db_column=db_column)
elif isinstance(field, models.AutoField):
return models.IntegerField()
return models.IntegerField(db_column=db_column)
elif not field.concrete: # pragma: no cover
# Django doesn't have any non-concrete fields that appear
# in ._meta.fields, but packages like django-prices have
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Generated by Django 4.2.6 on 2024-09-24 17:46

import pgtrigger.compiler
import pgtrigger.migrations
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("tests", "0013_concreteparent_concretechild_concretechildevent_and_more"),
]

operations = [
migrations.CreateModel(
name="CustomAutoFieldModel",
fields=[
(
"id",
models.AutoField(db_column="pk_id", primary_key=True, serialize=False),
),
],
),
migrations.CreateModel(
name="CustomBigAutoFieldModel",
fields=[
(
"id",
models.BigAutoField(db_column="pk_id", primary_key=True, serialize=False),
),
],
),
pgtrigger.migrations.RemoveTrigger(
model_name="ignoreautofieldssnapshotmodel",
name="update_update",
),
pgtrigger.migrations.RemoveTrigger(
model_name="ignoreautofieldssnapshotmodel",
name="delete_delete",
),
pgtrigger.migrations.AddTrigger(
model_name="ignoreautofieldssnapshotmodel",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition='WHEN (OLD."my_char_field" IS DISTINCT FROM (NEW."my_char_field") OR OLD."my_int_field" IS DISTINCT FROM (NEW."my_int_field"))', # noqa: E501
func='INSERT INTO "tests_ignoreautofieldssnapshotmodelcreatedatupdatedatmychardc6b" ("created_at", "my_char_field", "my_int_field", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at") VALUES (OLD."created_at", OLD."my_char_field", OLD."my_int_field", _pgh_attach_context(), NOW(), \'update\', OLD."id", OLD."updated_at"); RETURN NULL;', # noqa: E501
hash="e817c95f191e0d10b3e86643e2d8a050a864d45a",
operation="UPDATE",
pgid="pgtrigger_update_update_9dd1b",
table="tests_ignoreautofieldssnapshotmodel",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="ignoreautofieldssnapshotmodel",
trigger=pgtrigger.compiler.Trigger(
name="delete_delete",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "tests_ignoreautofieldssnapshotmodelcreatedatupdatedatmychardc6b" ("created_at", "my_char_field", "my_int_field", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "updated_at") VALUES (OLD."created_at", OLD."my_char_field", OLD."my_int_field", _pgh_attach_context(), NOW(), \'delete\', OLD."id", OLD."updated_at"); RETURN NULL;', # noqa: E501
hash="c112d8f78e576e8fc9a895c72a92567c20b093a4",
operation="DELETE",
pgid="pgtrigger_delete_delete_42ea6",
table="tests_ignoreautofieldssnapshotmodel",
when="AFTER",
),
),
),
]
8 changes: 8 additions & 0 deletions pghistory/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ class BigAutoFieldModel(models.Model):
id = models.BigAutoField(primary_key=True)


class CustomAutoFieldModel(models.Model):
id = models.AutoField(primary_key=True, db_column="pk_id")


class CustomBigAutoFieldModel(models.Model):
id = models.BigAutoField(primary_key=True, db_column="pk_id")


@pghistory.track(context_field=pghistory.ContextJSONField())
@pghistory.track(
pghistory.InsertEvent("snapshot_no_id_insert"),
Expand Down
6 changes: 6 additions & 0 deletions pghistory/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ def test_generate_history_field(settings):
field = pghistory.core._generate_history_field(test_models.BigAutoFieldModel, "id")
assert isinstance(field, models.BigIntegerField)

# AutoField and BigAutoField should take a custom column name from the original
field = pghistory.core._generate_history_field(test_models.CustomAutoFieldModel, "id")
assert field.db_column == "pk_id"
field = pghistory.core._generate_history_field(test_models.CustomBigAutoFieldModel, "id")
assert field.db_column == "pk_id"


@pytest.mark.django_db
def test_image_field_snapshot():
Expand Down

0 comments on commit 58a5513

Please sign in to comment.