connection.queries
で発行されたSQLを確認できるというDjangoの小ネタです。
DjangoのORMで発行されるSQLはQuerySetであれば以下のように確認できます。
In [1]: from myapp.models import Product In [2]: print(Product.objects.filter(id=1).query) SELECT "myapp_product"."id", "myapp_product"."name", "myapp_product"."price" FROM "myapp_product" WHERE "myapp_product"."id" = 1
しかし、この方法では都度.query
で確認しなければいけない上に、save
などのDML系の処理についてはSQLを確認できません。
他の方法として、一連の処理で発行されたSQLをすべて確認するのであればDB側で確認する手もあります。(MySQLのGeneralログなど) しかし、DjangoにはDBへのコネクションを介して発行されたSQLをすべて確認する方法もあります。それにはconnections.queries
を使用します。
In [1]: from django.db import connection In [2]: from myapp.models import Product, ProductOrder In [3]: Product.objects.filter(id=1).count() Out[3]: 0 In [4]: list(ProductOrder.objects.filter(id=1)) Out[4]: [] In [5]: for history in connection.queries: ...: print(history) ...: {'sql': 'SELECT COUNT(*) AS "__count" FROM "myapp_product" WHERE "myapp_product"."id" = 1', 'time': '0.001'} {'sql': 'SELECT "myapp_productorder"."id", "myapp_productorder"."product_id", "myapp_productorder"."amount", "myapp_productorder"."order_date" FROM "myapp_productorder" WHERE "myapp_productorder"."id" = 1', 'time': '0.000'}
このように発行されたSQL文と実行時間が記録されています。例ではSELECTだけですが、save
やdelete
で発行されたDMLについても記録されます。
また、この結果を途中でクリアする場合はreset_queries
を使用します。
In [6]: from django.db import reset_queries In [7]: len(connection.queries) Out[7]: 2 In [8]: len(connection.queries) # 一度取得しても結果はクリアされない Out[8]: 2 In [10]: reset_queries() In [11]: len(connection.queries) # 結果がクリアされている Out[11]: 0
なかなか便利ですが、settings.DEBUG
がTrue
の時しか記録されないのが残念ですね。用途を考えればあたりまではありますが・・・