django-cachalot
django-cachalot copied to clipboard
Patched cursor does not expect psycopg2 sql Composed Object
What happened?
I am integrating cachalot with my project and everything works fine up until the point we use django's ORM to execute queries, but in some parts of our project we use Raw SQLs and that's where this issue is happening. We are using psycopg2 native composition utility called sql
. Here the import for reference:
from psycopg2 import sql
Now this frames a Composed Object which when we try to execute using cursor like this:
with connection.cursor() as cursor:
cursor.execute(sql_query, query_args)
explodes in the cursors monkey_patch code which does not expect a compose object.
What should've happened instead?
I expect that cachalot should just allow these queries to run naturally and avoid caching them or at least make it a configurable setting.
Steps to reproduce
Configure cachalot in a django project and try to run any query using Raw sql and psycopg2 sql package for example:
from psycopg2 import sql
from django.db import connection
query = sql.SQL("select {field} from {table} where {pkey} = %s").format(
field=sql.Identifier('my_name'),
table=sql.Identifier('some_table'),
pkey=sql.Identifier('id'))
with connection.cursor() as cursor:
cur.execute(query, (42,))
django~=3.2 database=postgres 13.2
We don't support that unfortunately, but feel free to add a small if statement for your case. In the meantime, you can use a utility function to temporarily disable cachalot.
Sure @Andrew-Chen-Wang , once I get some spare time will raise a PR for the above, I'll just raise a warning when encountering sql other than string, and let it execute without bothering caching. Does it sound good?
Correct. Unsupported measures raise an exception that exits the monkeypatch.
We're evaluating using the lib in our project and faced similar issue. We utilise psycopg2.sql
API to make using raw SQL safer.
I can confirm that adding CACHALOT_INVALIDATE_RAW = False
allows to workaround the issue.
In the meantime, you can use a utility function to temporarily disable cachalot. @Andrew-Chen-Wang if you were referring to
cachalot.api.cachalot_disabled
then it doesn't help, probably becausecachalot.monkey_patch._patch_cursor
only checks forCACHALOT_INVALIDATE_RAW
and not theLOCAL_STORAGE
.