In the Django 1.8 release notes, it mentions that Django Fields no longer use SubfieldBase, and has replaced the to_python call on assignment with from_db_value.
The docs also state that from_db_value is called whenever data is loaded from the database.
My question is, is from_db_value called if I directly read/write the db (i.e. using cursor.execute())? My initial tries and intuition says no, but I just want to make sure.
See The Django Documentation for Executing custom SQL directly.
Sometimes even Manager.raw() isn’t quite enough: you might need to perform queries that don’t map cleanly to models, or directly execute UPDATE, INSERT, or DELETE queries.
In these cases, you can always access the database directly, routing around the model layer entirely.
The above states that using cursor.execute() will bypass the model logic entirely, returning the raw row results.
If you want to perform raw queries and return model objects, see the Django Documentation on Performing raw queries.
The raw() manager method can be used to perform raw SQL queries that return model instances:
for p in Person.objects.raw('SELECT * FROM myapp_person'):
print(p)
>>> John Smith
>>> Jane Jones
Related
I am building an app with Django relying on several PosgreSQL databases which I do not manage, let's call them database A and database B. For each database, I've used python manage.py inspectdb to build my models.py files.
I am trying to use Django ORM to perform the following query (significantly simplified here), to_date being a datetime.datetime object:
sample = my_model_in_B.objects\
.filter(a_column=instance_of_a_model_in_A.name)\
.exclude(another_column='Useless things')\
.filter(a_column_with_dates__lte=to_date)
My issue is that it produces the following SQL query:
SELECT "myschema"."mytable"."a_column", "myschema"."mytable"."another_column" from "myschema"."mytable"
WHERE "myschema"."mytable"."a_column" = Here is the name of instance_of_a_model_in_A
AND "myschema"."mytable"."a_column_with_dates" <= 2020-02-03
AND NOT ("myschema"."mytable"."another_column" = Useless things
AND "myschema"."mytable"."another_column" IS NOT NULL))
In other terms, my issue is that the Django ORM does not automatically add quotes where I need them. I don't understand what I did wrong. I don't know if that matters but note that:
I use Django 2.2. and my database B is POSTGRESQL 8 only,
All the columns that I use correspond to CharField in my models, except a_column_with_dates which corresponds to a DateField.
Actually, my initial question was wrongly worded and misleading. I was assuming that QuerySet.query (that I used to get the above SQL code) was supposed to return the valid SQL query behind Django ORM, but it isn't. It just aims at providing a basic representation of the query, nonetheless, from a comment made on the official Django project website:
Django never actually interpolates the parameters: it sends the query
and the parameters separately to the database adapter, which performs
the appropriate operations.
Indeed, from the official documentation:
The query parameter to QuerySet exists so that specialized query subclasses can reconstruct internal query state. The value of the parameter is an opaque representation of that query state and is not part of a public API.
Django official docs state that:
In some rare circumstances, it’s necessary to be able to force the save() method to perform an SQL INSERT and not fall back to doing an UPDATE. Or vice-versa: update, if possible, but not insert a new row. In these cases you can pass the force_insert=True or force_update=True parameters to the save() method. Obviously, passing both parameters is an error: you cannot both insert and update at the same time!
What are these rare circumstances?
Basically, when should one use force_update=True?
I'm building a web app using Django and couchdb 2.0.
The new version of couchdb doesn't support temporary views. They recommend using a Mongo query but I couldn't find any useful documentation.
What is the best approach or library to use couchdb 2.0 with Django?
Temporary views were indeed abandoned in CouchDB 2.0. With mango, you could emulate them using a Hack, but that's just as bad (read: performance-wise). The recommendation is to actually use persistent views. As only the delta of new or updated documents need indexing, this will likely need significantly less resources.
As opposed to relational DBs, the created view (which is a persisted index by keys), is meant to be queried many times with different parameters (there is no such a thing as a query optimizer taking your temp view definition or something). So, when you're built heavily on temporary views, you might consider changing the way you query in the first place. One place to start is thinking about which attribute will collapse the result set most quickly to what you're looking for and build a view for that. Then, go query this view with keys and post-filter for the rest.
The closest thing you can do to a temporary view (when you really, really need it) is creating a design doc (e.g. _design/temp<uuid>) and use it for the one query execution.
Just to add a link (not new - but timeless) on the details: http://guide.couchdb.org/draft/views.html
So I'm currently working in Python/Django and I have a problem where Django caches querysets "within a session".
If I run python manage.py shell and do so:
>>> from myproject.services.models import *
>>> test = TestModel.objects.filter(pk = 5)
>>> print test[0].name
>>> John
Now, if I then update it directly in SQL to Bob and run it again, it'll still say John. If I however CTRL+D out (exit) and run the same thing, it will have updated and will now print Bob.
My problem is that I'm running a SOAP service in a screen and it'll always return the same result, even if the data gets changed.
I need a way to force the query to actually pull the data from the database again, not just pull the cached data. I could just use raw queries but that doesn't feel like a solution to me, any ideas?
The queryset is not cached 'within a session'.
The Django documentation: Caching and QuerySets mentions:
Each QuerySet contains a cache to minimize database access. Understanding how it works will allow you to write the most efficient code.
In a newly created QuerySet, the cache is empty. The first time a QuerySet is evaluated – and, hence, a database query happens – Django saves the query results in the QuerySet’s cache and returns the results that have been explicitly requested (e.g., the next element, if the QuerySet is being iterated over). Subsequent evaluations of the QuerySet reuse the cached results.
Keep this caching behavior in mind, because it may bite you if you don’t use your QuerySets correctly.
(emphasis mine)
For more information on when querysets are evaluated, refer to this link.
If it is critical for your application that he querysets gets updated, you have to evaluate it each time, be it within a single view function, or with ajax.
It is like running a SQL query again and again. Like old times when no querysets have been available and you kept the data in some structure that you had to refresh.
I am quite new to Python and I have seen that both
Entries.objects.raw("SELECT * FROM register_entries")
and
Entries.objects.filter()
do the same query.
In which cases is better to use one or the other?
It depends on the database backend that you are using. The first assume that you have a SQL-based database engine. That is not always true. At the opposite, the second one will work in any case (if the backend is designed for). There was for instance few years ago a LDAP backend which was designed so, but LDAP queries do not use SQL language at all.
In all cases, I advice you to use the second one. It is the better way to go if you want to make reusable and long-term code.
There are also other ideas to prefer the second one to the first one
avoiding possible SQL injections ;
no need to know about database design (table's name, fields' name) ;
generic code is better than specific one ;
and moreover, it is shorter...
But you sometimes will have to use the first one when you do specific operations (calling specific backend's functions), but avoid them as much as possible.
In a nutshell, use the second one!!!
From django documentation:
When the model query APIs don’t go far enough, you can fall back to writing raw SQL
For all aspects, django queryset api offers you many options to customize your queries. But in some cases, you need to use very specific queries where django api become insufficient. But before you go for raw SQL, it is best to read all Queryset Api docs and learn everything about django queryset api.