いつもお世話になっております。
早速本題に入らせていただきます。
現在、DjangoとPythonを使用してWebアプリケーションを制作しているのですが、
データが既に登録されているデータベースに対してレコードを新規登録する際、
AutoField にしたIDが 自動採番されず、キー重複エラー が出てしまいます。
以下が現在のコードとなります。
models.py
Python
1class TestMaster(models.Model): 2 class Meta: 3 db_table = 'test_master' 4 5 test_id = models.AutoField(verbose_name="ID", primary_key=True) 6 title = models.CharField(verbose_name="タイトル", null=False) 7 content = models.CharField(verbose_name="本文", null=False) 8 creator = models.CharField(verbose_name="作成者" null=False)
views.py やったことその1
Python
1TestMaster.objects.create(title="title", 2 content="content", 3 creator="ADMIN" 4 )
views.py やったことその2
Python
1b2 = TestMaster(title="title", 2 content="content", 3 creator="ADMIN" 4 ) 5b2.save()
** 出力されたエラー文**
重複キーが一意性制約"test_master_pkey"に違反しています DETAIL: キー (test_id)=(1) はすでに存在します。
DBに直接レコードを追加してしまったがためにAutoFieldが機能していないのか、
それともただ単に書き方が悪いのか・・・
お時間ある方でAutoField設定項目について知識をお持ちの方いらっしゃいましたらご助力頂けますと幸いです。
調査した結果の追記
Django ってDBを直接編集することを想定してないのか・・・?
どうやったら同期とれるんだ・・・
登録する前にidの最大値とってくるしかないのか・・・?
かなしみの暫定対応
Python
1entry = TestMaster.objects.all().aggregate(Max('test_id')) 2 3 TestMaster.objects.create(test_id=entry["test_id__max"] + 1, 4 title=title, 5 content=content, 6 creator=user 7 )
排他制御入れないとだめそう?だけど一応これなら自動採番もどきはできる・・・
けど自動採番したい・・・
「Djangoでは、モデルのプライマリーキーがシーケンスによって決まります。」
シーケンス・・・?と思ってDBを見てみれば確かに自動採番するときにシーケンスの次の番号を入れようとしてるらしい。
↓
じゃあ手運用後にシーケンスの値合わせてあげれば解決するのでは?
シーケンスの値を変更をするには
SELECT setval('test_master_test_id_seq', (SELECT MAX(test_id) FROM test_master));
↓
Python
1TestMaster.objects.create(title="title", 2 content="content", 3 creator="ADMIN" 4 )
↓
DBに ID=101 で登録された!
結論
- pgAdminで手動でレコード追加する場合は シーケンスを更新してあげないといけない
- ↑が嫌なら、自動採番じゃなくてUUIDなどに変更すべき
個人的にはシーケンス更新が楽な気がするのでとりあえず解決
同じ事象で困っている方の役に立ちますように。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/07 01:54