How can you get the SQL for a Django model's .save(), i.e.
from django.db import models
class MyM(models.Model):
text = models.TextField()
How can you get the SQL that would be created/used in the following scenario:
>>> m = MyM(text="123")
>>> m.save()
# What SQL Django just run?
Thanks!
Documentation and source is available at http://django-debug-toolbar.readthedocs.io/. debug_toolbar is especially useful when you have a query that's failing with a SQL syntax error; it will display the last query that attempted to run (and failed), making it easier to debug.
Saving objects. To save an object back to the database, call save() : Model.
Creating objects To create an object, instantiate it using keyword arguments to the model class, then call save() to save it to the database. This performs an INSERT SQL statement behind the scenes. Django doesn't hit the database until you explicitly call save() . The save() method has no return value.
Django gives you two ways of performing raw SQL queries: you can use Manager. raw() to perform raw queries and return model instances, or you can avoid the model layer entirely and execute custom SQL directly. Explore the ORM before using raw SQL!
If you want get the insert statement for model before saving - you can use the following code (checked on 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]
From the Django FAQ:
How can I see the raw SQL queries Django is running? Make sure your Django DEBUG setting is set to True. Then, just do this:
>>> 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'}]
db.queries is only available if DEBUG is True. It's a list of dictionaries in order of query execution. Each dictionary has the following:sql
--The raw SQL statementtime
-- How long the statement took to execute, in seconds.
db.queries includes all SQL statements -- INSERTs, UPDATES, SELECTs, etc.
Just run python manage.py sqlall APP_NAME
.
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
Then call it such as
model_to_insert_sql([your_model_1, your_model_2])
for a bulk insert. If only want a single insert, call it as
model_to_insert_sql([your_model])
p.s. @Kerrigan's answer cannot compile, and does not work with string types...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With