Why .query() function not working on Django ORM query? - python

As I already know that using .query.__str__() , we can get sql equivalent query from Django ORM query.
e.g : Employees.objects.filter(id = int(id)).query.__str__()
Above code working well & I am able to get sql equivalent query
but when I am using same on below query I am getting error like below.
Employees.objects.filter(id = int(id)).first().query.__str__()
AttributeError: 'Employees' object has no attribute 'query'
Why now I am getting error, any suggestions ?

.first() [Django-doc] does not return a QuerySet, it returns a model object. The query is evaluated eagerly.
You can inspect the last query that Django made with:
from django.db import connection
print(connection.queries[-1:])
That being said, in essence a some_queryset.first() is often the same query as some_queryset, except that it will limit the queryset.
Note: Please do not use .__str__, you can use str(my_queryset.query), or just print(my_queryset.query).

Related

How to see the underlying query which includes count() in it, in django

I have the following code in a Django 2 project
print(List.objects.filter(user=self.request.user).query)
which prints the SQL query which is constructed
but the following
print(List.objects.filter(user=self.request.user).count().query)
throws error
print(List.objects.filter(user=self.request.user).count().query)
AttributeError: 'int' object has no attribute 'query'
I know why it happens, because count() immediately return the count.
How do I see the query which it constructed
List.objects.filter(user=self.request.user).count()
This line returns count as type int and integer type has no attribute query, but you can see the sql query behind this in your django shell
from django.db import connection
List.objects.filter(user=self.request.user).count()
connection.queries[-1]['sql']
connection.queries returns list of dictionaries in that shell session.
Also don't name your model List. It is a reserved keyword.

Create Django QuerySet from Oracle table-valued Function

I try to create a Django QuerySet from an Oracle table-valued Function
qs = MyModel.objects.raw("SELECT * FROM TABLE(My-table-valued-Function)")
As soon as I evaluate the query set I get the error:
django.db.utils.DatabaseError: ORA-00942: table or view does not exist
Does anybody have a solution for this?
After some debugging I figured out that Django adds a table name to the SQL statement when evaluating the QuerySet including an Oracle table function:
XX.objects.raw("SELECT 1 as id, PROJEKT FROM TABLE(my_table_function())")
becomes
SELECT "CHARTS_XX"."ID", "CHARTS_XX"."PROJEKT" FROM "CHARTS_XX" WHERE CHARTS_XX"."ID" = %s
where "charts" is my app name and "XX" my Model.
Is there any way to force Django to use the table function?
Thanks!
Thorx

Apply Python Code To Sqlalchemy Filters

I'm trying to figure out how to apply python code (like splitting a list) to a sqlalchemy filter. An example is as follows: my database stores a full name as a field in the table. I want to query my database for all people who have a given first name. So what I want to do is something like:
User.query.filter(User.name.split()[0].lower() == 'henry'.lower())
When I try to run this query, I get the error:
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with User.name has an attribute 'split'
What is the general way to apply python commands like split(), lower(), etc. to my sqlalchemy queries?
SQLAlchemy is constructing a SQL expression, not a Python expression. You can apply SQL functions to the expression by using the func object.
from sqlalchemy import func
User.query.filter(func.lower(func.substring_index(User.name, ' ', 1)) == 'henry')

Curious about how django achieves the ORM query optimization

I am no python expert and I am curious about how django optimize the following query
Model.objects.filter(field = 'abc')[0]
Somehow django will intelligently add 'limit 1' to SQL query like 'select * from model where field = 'abc' limit 1'
This is because Model.objects.filter(...) doesn't actually return a list, it returns a queryset object. When you do qset[0], it calls the __getitem__ method on querysets, which adds the limit 1 and executes it. Here's the source of that method; there's logic for various cases when the result has already been cached or not and so on.

Getting the SQL from a Django QuerySet

How do I get the SQL that Django will use on the database from a QuerySet object? I'm trying to debug some strange behavior, but I'm not sure what queries are going to the database.
You print the queryset's query attribute.
>>> queryset = MyModel.objects.all()
>>> print(queryset.query)
SELECT "myapp_mymodel"."id", ... FROM "myapp_mymodel"
Easy:
print(my_queryset.query)
For example:
from django.contrib.auth.models import User
print(User.objects.filter(last_name__icontains = 'ax').query)
It should also be mentioned that if you have DEBUG = True, then all of your queries are logged, and you can get them by accessing connection.queries:
from django.db import connections
connections['default'].queries
The django debug toolbar project uses this to present the queries on a page in a neat manner.
The accepted answer did not work for me when using Django 1.4.4. Instead of the raw query, a reference to the Query object was returned: <django.db.models.sql.query.Query object at 0x10a4acd90>.
The following returned the query:
>>> queryset = MyModel.objects.all()
>>> queryset.query.__str__()
This middleware will output every SQL query to your console, with color highlighting and execution time, it's been invaluable for me in optimizing some tricky requests
http://djangosnippets.org/snippets/290/
As an alternative to the other answers, django-devserver outputs SQL to the console.

Categories