获取Django模型在.保存()上拥有(或将要调用)的SQL

46qrfjad  于 2023-05-23  发布在  Go
关注(0)|答案(4)|浏览(157)

如何获取Django模型的.保存()的SQL,即

from django.db import models

class MyM(models.Model):
   text = models.TextField()

如何获取将在以下场景中创建/使用的SQL:

>>> m = MyM(text="123")
 >>> m.save()
 # What SQL Django just run?

谢谢!

brjng4g3

brjng4g31#

如果你想在保存之前获取model的insert语句-你可以使用下面的代码(在django 1.4中检查)

from django.db import connection
from django.db.models import sql

def object_to_query(objects):
    if isinstance(objects, (list, tuple)
    values = obj._meta.local_fields
    q = sql.InsertQuery(obj)
    q.insert_values(values, [obj])
    compiler = q.get_compiler('default')
    # Normally, execute sets this, but we don't want to call execute
    setattr(compiler, 'return_id', False)
    stmts = compiler.as_sql()
    stmt = [stmt % params for stmt, params in stmts]
    return stmt[0]
ne5o7dgx

ne5o7dgx2#

Django FAQ:
如何查看Django正在运行的原始SQL查询?确保你的Django DEBUG设置为True。然后,只需这样做:

>>> from django.core.db import db  
>>> db.queries  
[{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls',   
'time': '0.002'}]

只有当DEBUG为True时,db.queries才可用。它是按查询执行顺序排列的字典列表。每个字典都有以下内容:
sql--原始SQL语句
time--执行语句所用的时间,以秒为单位。
queries包括所有的SQL语句--INSERT、UPDATES、SELECTs等。

6l7fqoea

6l7fqoea3#

from django.db.models import sql, Model
from typing import List

def _escape_sql_param(param):
    if type(param) is str:
        return f"'{param}'"
    return str(param)

# noinspection PyProtectedMember
def model_to_insert_sql(models: List[Model]):
    fields = models[0]._meta.local_fields
    q = sql.InsertQuery(models[0])
    q.insert_values(fields, models)

    compiler = q.get_compiler('default')
    # Normally, execute sets this, but we don't want to call execute
    setattr(compiler, 'return_id', False)
    raw_statements = compiler.as_sql()

    mixed_statements = [statement % tuple(_escape_sql_param(param) for param in params)
                        for statement, params in raw_statements]
    return mixed_statements

那就叫它如

model_to_insert_sql([your_model_1, your_model_2])

用于批量插入。如果只需要一个插入,则将其称为

model_to_insert_sql([your_model])

p.s. @Kerrigan的答案无法编译,并且不适用于字符串类型...

dgtucam1

dgtucam14#

运行python manage.py sqlall APP_NAME

相关问题