How do you view the SQL generated by Django for a DELETE?
When doing a SELECT operation on a query set, you can do this:
>>> qs = Entry.objects.filter(date__gt='2010-06-01')
>>> qs.query.as_sql()
('SELECT ...)
But I don't know how to get the SQL for what happens when I do qs.delete().
It looks a bit more involved because Django "emulates the behavior of the SQL constraint ON DELETE CASCADE" when deleting objects.
(Background: trying to debug an IntegrityError generated by a foreign key constraint when deleting a subclassed model object.)
This works well enough:
>>> from django.db import connection
>>> connection.queries[:-10]
Thought the exceptions occurred before the queries were added to connection.queries, but they are indeed present.
Here's another method which relies on Django internals and doesn't include queries to do cascading deletes, but doesn't require executing the query:
from django.db.models import sql
qs = Entry.objects.filter(date__gt='2010-06-01')
query = qs.query.clone()
query.__class__ = sql.DeleteQuery
print(query)
You could try running django-debug-toolbar and see the queries that way.
Related
I have written this in django
a = Model.objects.all()
Will this query execute immediately or not?
When will this query fetch the request from the db?
In Django the Querysets are lazy i.e. when you create a queryset, it will involve any database activity,unless the queryset is evaluated.Read this Documentation for more in depth information.
I have a QuerySet with a prefetch_related() (with Prefetch object)
I want to see the raw query and print(qs.query) and it doesn't show anything about the prefetch_related stuff.
How do I see the query which will be run because of prefetch_related?
The queryset's query object will only show you the query that Django generates for the queryset itself (before any prefetch_related etc. is applied).
You probably need to look at these guidelines for inspecting the query that is actually sent to your database:
from django.db import connection
print(connection.queries)
Alternatively you can use something like django-debug-toolbar to display the queries.
I am working on a data migration for a Django app to populate
the main table in the db with data that will form the mainstay of
the app - this is persistent/permanent data that may added to but
never deleted.
My reference is the Django 1.7 documentation and in particular an
example on page
https://docs.djangoproject.com/en/1.7/ref/migration-operations/#django.db.migrations.operations.RunPython
with a custom method called forward_funcs:
def forwards_func(apps, schema_editor):
# We get the model from the versioned app registry;
# if we directly import it, it'll be the wrong version
Country = apps.get_model("myapp", "Country")
db_alias = schema_editor.connection.alias
Country.objects.using(db_alias).bulk_create([
Country(name="USA", code="us"),
Country(name="France", code="fr"),])
I am assuming the argument to bulk_create is a list of Country model objects not namedtuple objects, although the format looks exactly the same. Is this the case, and could someone please explain what db_alias is?
Also, if I wish to change or remove existing entries in a table using a data migration what are the methods corresponding to bulk_create to do this?
Thanks in advance for any help.
Country is just the same as you would do from app.models import Country. Only thing different, the import always gives you the latest model and apps.get_model in a migration gives you the model at the time of the migration. It continues to edit the model within the initial migration.
About bulk_create; its argument is indeed a list of unsaved Country objects and uses it to do an huge insert into your db. More information about bulk_create can be found here; https://docs.djangoproject.com/en/1.7/ref/models/querysets/#bulk-create.
About db_alias, it is the name of the database you set within your settings. Most of the time it is default, so you can leave it in your code if you just use one database. The function will probably will called more than once if you have more databases set within your settings. More info about using; https://docs.djangoproject.com/en/1.7/ref/models/querysets/#using.
An bulk delete is actually quite simple, you just filter your Countries and call delete on the queryset. So something like;
Country.objects.filter(continent="Europe").delete()
About the persistent/permanent data question, I don't really have a solution for that one. One thing you can do, I think, is overwrite the .delete() function on the model and Manager.
How can I check, which query django 1.4.11 generates for this query:
obj = Model.objects.get(code='code')
I've tried:
print Model.objects.get(code='code').query
but there is such method for model object.
How can I get raw sql?
It doesn't work because query is a property of the Queryset object and when you do a .get() the Queryset it´s evaluated (and became an instance of Model)
If you try:
>>> type(Model.objects.get(code='code'))
<class 'app.models.Model'>
>>> print Model.objects.get(code='code').query
AttributeError: 'Model' object has no attribute 'query'
But instead with:
>>> type(Model.objects.all())
<class 'django.db.models.query.QuerySet'>
>>> print Model.objects.all().query
SELECT "model.Model" from ...
Now, to get the SQL of all the queries you have several options:
If DEBUG=True you can use this:
from django.db import connection
print connection.queries
Use django-debug-toolbar
Use the built-in django logging https://docs.djangoproject.com/en/dev/topics/logging/#django-db-backends You can find examples on how to setup here in SO.
Upon initialization of an application in django, before the postgresql database has been created, if one tries to get/all/create an object they will usually see an error like this:
>>> Model.objects.all()
{StackTrace}
...
DatabaseError: relation "model" does not exist
...
In my application I would like to be able to test for the models existence and run code if it exists, is this possible using django?
Pseudocode:
if not (table_exists(model))
return
my_models = Model.objects.all()
...
You could catch the exception that's thrown while trying to access the model:
from django.db import DatabaseError
try:
Model.objects.exists()
except DatabaseError:
print 'DB not yet initialized'
else:
print 'DB table exists'
I don't know why you would want to do this, but could you just issue raw sql to see if the table exists??
SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';