こんにちは。sinyです。
一番大好きなWEBフレームワーク「Django」でこれまで扱ったちょっとしたノウハウをまとめた記事を書いてみました。
今回は「データベース操作」に関連するノウハウです。
まだまだ数が少ないですが、いろんなカテゴリ毎に記事をまとめて、継続的に更新していきたいと思います。
Djangoデータベース操作編
MySQLのpkキーの自動増加(increment)を0にリセットする方法
テストなどでレコードを追加⇒削除を繰り返していくと、テーブルのPKキーの番号がどんどん増えていくので、「初期化したい!」というケースがあると思います。
今回はMySQLですが、以下の手順でincrementを1に初期化することができます。
MySQLのDBに接続して以下のalterコマンドを実行するだけです。
use <データベース名>; alter table <テーブル名> auto_increment = 1;
これだけだとネットにもよく転がっている情報だと思いますので、ちょっとした応用編を。
例えば、Djangoカスタムコマンドを利用(バッチ処理化)して定期的にあるテーブルのデータを全件入れなおしたいとします。
テーブルをTruncateする場合はテーブルのAUTO_INCREMENTの値も0に初期化されるので問題ないですが、TruncateではなくDeleteで実現したいというケースの場合、AUTO_INCREMENTの値は保持されるためリセットされません。
この場合は、先ほど説明した「alter table <テーブル名> auto_increment = 1;」といったコマンドを実行すればいいのですが、テーブル属性の変更という位置づけのためなのか、Djangoカスタムコマンド内で上記コマンドをそのまま実行してもエラーになってしまいます。
この場合、以下のようなコードでincrementをリセットすることができます。
from django.db import connection cursor = connection.cursor() cursor.execute('alter <table_name> auto_increment = 1')
これを応用すれば、他のalterコマンドもバッチ処理内で実行できると思います。
Foreign Keyを持たないテーブル間の結合例
例えば以下のようなテーブルクラスをmodels.pyで定義していたとします。
class AAA(models.Model): class Meta: verbose_name = 'AAA' verbose_name_plural = 'AAA' columnA1 = models.CharField(max_length=255) columnA2 = models.CharField(max_length=255) class BBB(models.Model): class Meta: verbose_name = 'BBB' verbose_name_plural = 'BBB' columnB1 = models.CharField(max_length=255) columnB2 = models.CharField(max_length=255) columnB3 = models.CharField(max_length=255)
AAAテーブルとBBBテーブル間には外部キーの関係がありませんが、AAAテーブルのカラム(columnA1)とBBBテーブルのカラム(columnB1)には同じ意味を成すデータ(例えばユーザ名など)が格納されていて、BBBテーブルに登録されているユーザだけに絞り込んでAAAテーブルから該当のユーザ情報を抽出したいといった場合があるとします。
この場合は、以下のようなクエリを書くと希望する情報を抽出することができます。
AAA.objects.all().filter(columnA1__in=[BBB.objects.values_list('columnB1',flat=True)]
values_listを使うと抽出結果をリスト形式で取得することができます。
取得したリスト形式のcolumnB1の情報を「in =」に渡してあげることで、「BBBテーブルのcolumnB1のいづれかに該当するAAAテーブルのcolumnA1を取得する」という感じで実現できます。
Djangoのデータベース操作に関するノウハウは、随時、本記事内で更新していきます。