Diego Magalhães
Diego Magalhães

Reputation: 1762

Django trying to save object with existing primary key

Today something strange happened. I'm importing data from a payment gateway after request:

for signature in response.json:
    Signature.objects.get_or_create(**signature)

json example:

[
  {'id': 1, 'plan': 1, 'customer': 1},
  {'id': 31, 'plan': 12, 'customer': 22}
  {'id': 2, 'plan': 3, 'customer': 50},
  {'id': 3111, 'plan': 12, 'customer': 22},
  {'id': 222, 'plan': 12, 'customer': 22},
]

Yes, my client didn't follow an ID sequence registering signatures manually on payment service so, I'm importing and keeping the same pk.

This code works as expected and data is now synced with payment service (all objects imported).

Now the strange behavior:

I'm using Django Rest Framework and after a POST (check validated_data) in my API the following error raises at this line:

Signature.object.create(**self.validated_data)

duplicate key value violates unique constraint "plans_signature_pkey" DETAIL: Key (id)=(1) already exists.

validated data:

{
   "plan": "3", # This is a foreign key to plan 3
   "payer_only": False,
   "schedule": "09:00",
   "payment_method: "CREDIT_CARD"
}

There is no 'pk': 1 or 'id': 1 in validated data

Django is trying to create an object with an existing key?

Debugging code, I called the Subscription.create() line 31 times then:

duplicate key value violates unique constraint "plans_signature_pkey" DETAIL: Key (id)=(1) already exists.

....

duplicate key value violates unique constraint "plans_signature_pkey" DETAIL: Key (id)=(31) already exists.

On call 32 this works. So, am I missing something? This looks a weird behavior to me.

Upvotes: 4

Views: 1788

Answers (1)

Diego Magalhães
Diego Magalhães

Reputation: 1762

After a long research I've found the solution. I'm using POSTGRES and Django uses PostgreSQL’s SERIAL data type to store auto-increment keys. A manual primary key assign stops the pk auto-increment. The solution: sqlsequencereset

$ django-admin sqlsequencereset app_label

"Use this command to generate SQL which will fix cases where a sequence is out of sync with its automatically incremented field data."

Upvotes: 9

Related Questions