django の model に AutoField ってわけではなく、
別途シーケンスオブジェクトから、採番した番号とあるカラムに設定したくて、
調べた結果を記載します。
前提
環境情報は以下の通りです。
- OS
sw_vers
----------------------------
ProductName: Mac OS X
ProductVersion: 10.11.6
BuildVersion: 15G1108
----------------------------
- python version
python3 -V
----------------------------
Python 3.5.1
----------------------------
- Django Version
pip list
----------------------------
Django (1.10)
----------------------------
- DB
psql -V
----------------------------
psql (PostgreSQL) 9.5.2
----------------------------
自前でシーケンスオブジェクトを作成し、シーケンス取得クエリを発行する
Django 1.7 で、マイグレーションファイルでフルテキストインデックスを作成する | ytyng.com と、
sql - Trying to get the next value in sequence from a postgres DB, with django - Stack Overflow と、
Django, accessing PostgreSQL sequence - Stack Overflow を
見る限り、
-
Migration を書いて create sequence を作成する。
-
select nextval でシーケンスを採番する。
方式で、できそうです。
Migration を書いて create sequence を作成する。
- 空のマイグレーションファイルを作成する
./manage.py makemigrations festivals4partypeople --empty
------------------------------------------
Migrations for 'festivals4partypeople':
festivals4partypeople/migrations/0046_auto_20161125_0145.py:
------------------------------------------
- マイグレーションファイルに
migrations.RunSQL
で create sequence 文 を書く
0046_auto_20161125_0145.py を 修正して、
create sequence を 追加しました。
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-11-24 16:45
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('festivals4partypeople', '0045_auto_20161124_2238'),
]
operations = [
"CREATE SEQUENCE festival_classification_seq ",
]
- migrate 実行
./manage.py migrate
-----------------------------------
Operations to perform:
Apply all migrations: admin, auth, contenttypes, festivals4partypeople, sessions
Running migrations:
Applying festivals4partypeople.0046_auto_20161125_0145... OK
-----------------------------------
- シーケンス取得メソッド作成
@staticmethod
def __create_festival_classification_seq():
from django.db import connection
cursor = connection.cursor()
cursor.execute("select nextval('festival_classification_seq')")
result = cursor.fetchone()
return result[0]
という形で、シーケンスは発行できました。
django-sequences を使ってシーケンスを発行する
aaugustin/django-sequences: Generate gap-less sequences of integer values.
というシーケンス発行ライブラリがあるので、そちらについて記載します。
dbシーケンスを使うのではなく、
simple な シーケンス発行Tableを使って連番を作るライブラリのようです。
インストール
django-sequences/README.rst at master · aaugustin/django-sequences
に従って、インストールします。
pip install django-sequences
-------------------------------------------
Collecting django-sequences
Downloading django_sequences-1.0.1-py2.py3-none-any.whl
Installing collected packages: django-sequences
Successfully installed django-sequences-1.0.1
-------------------------------------------
settings.py に django-sequences を追加する
INSTALLED_APPS += ['sequences.apps.SequencesConfig']
migrate 実行
python3 manage.py migrate
------------------------------------------
TypeError: can only concatenate tuple (not "list") to tuple
------------------------------------------
INSTALLED_APPS が tuple だったらしいので以下の通り修正
INSTALLED_APPS = (
'festivals4partypeople',
'festivals_crawler.apps.FestivalsCrawlerConfig',
'django_extensions',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'sequences.apps.SequencesConfig'
)
再度、migrate を実行
python3 manage.py migrate
------------------------------------
Operations to perform:
Apply all migrations: admin, auth, contenttypes, festivals4partypeople, sequences, sessions
Running migrations:
Applying sequences.0001_initial... OK
------------------------------------
シーケンス採番
以下のように書けます。
-
python 記述
from sequences import get_next_value print(get_next_value('festival_classification_seq'))
-
output ※2回採番しています。
2
採番テーブル
postgress では、以下のテーブルができていました。
-
SQL
select * from sequences_sequence;
-
output
name | last -----------------------------+------ festival_classification_seq | 2 (1 row)
どちらがいいのか
高負荷時はシーケンスとして作る方が、早いけど、
別に動くうちは、django-sequences の方が楽かなと。
今は、シーケンス自体それほど使わないので、
個人的には、自前でシーケンスオブジェクトを作成し、シーケンス取得クエリを発行する
方式でいこうかなと思います。
以上です。
コメント