PUROGU LADESU

ポエムがメインのブログです。

【Django】素のSQL文の実行

パターンは2つある

1.モデルオブジェクトに紐づける(SELECTの場合)
2.モデルに関係ないSQLを実行する(INSERT, UPDATE, DELETE, モデル生成しないSELECT)

1.モデルオブジェクトに紐づける

detail = DailyReportDetail.objects.raw("SELECT * FROM reportapp_dailyreportdetail WHERE id = %s", [6])[0]
detail.save()

結果はモデルオブジェクトになるので、モデルに合ったテーブルを指定している必要がある。

モデルを使うなら、主キーは必ずSELECTに含める(ないとエラー)
SELECTにないフィールドを参照したら、その時点で追加のクエリが発行される

2.モデルに関係ないSQLを実行する

INSERT, UPDATE, DELETEはこちら。
SELECTでモデルじゃなく単なる値を取りたい場合もこちら。

from django.db import connection
with connection.cursor() as cursor:
    cursor.execute("UPDATE myapp_person SET flag = 1 WHERE last_name = %s", [name])

with connection.cursor() as cursor:
    cursor.execute("SELECT flag FROM myapp_person WHERE last_name = %s", [name])
    row = cursor.fetchone() タプルで返される
    row = cursor.fetchall() 複数結果、タプルのリスト
    cursor.description タプルの1個目がフィールド名みたい -> [x[0] for x in cursor.description]

fetchone(), fetchall() はレコードをリストで返してくる。名前はつかない。
名前をつけたい場合はnamedtupleを使う。
descriptionを渡してフィールド名を定義し、レコード配列を渡す。

nt_res = namedtuple("Result", [x[0] for x in cursor.description])
res = nt_res(*row)

素の SQL 文の実行 | Django ドキュメント | Django