desde django.db.models.Value, no se incluyen comillas al convertirlo en una cadena de consulta.
Estoy utilizando la expresión django.db.models.Value
dentro de una función QuerySet en Django 3.2.8. Cuando paso un valor en forma de cadena ("|"
en mi ejemplo a continuación), la conversión a una cadena de consulta no agrega el '
, lo que provoca que la consulta falle.
from django.db import models
from django.db.models import F, Value
from django.db.models.functions import Concat
class PurchaseOrder(models.Model):
id = models.AutoField(primary<em>key=True)
customer</em>name = models.CharField(max_length=50)
date = models.DateField()
qs = PurchaseOrder.objects.annotate(
concat=Concat(
F("customer<em>name"),
Value("~"),
F("date"),
output</em>field=models.CharField(),
)
).values("concat")
print(str(qs.query))
SELECT CONCAT("purchaseorder"."customer_name", CONCAT(~, "purchaseorder"."date")) AS "concat" FROM "purchaseorder"
Como se puede ver en el resultado anterior, falta el carácter ~
a los dos '
que deberían envolverlo: CONCAT('~', "purchaseorder"."date")
.
¿Es esta la funcionalidad esperada de la expresión Value
o es un error que se debe informar? Tengo la inclinación de creer que es un error, debido a lo siguiente:
Inicialmente resolví el problema anterior escribiéndolo como Value("'~'")
, con los dos '
dentro de mi cadena. Sin embargo, al ejecutar la consulta en una base de datos sqlite3 durante las pruebas unitarias, obtuve un error en la consulta. Me di cuenta de que sqlite tiene una sintaxis diferente a Postgres (mi base de datos de producción y desarrollo local) para la función Concat:
- Postgres:
CONCAT([args])
- Sqlite:
arg1 || arg2 ...
En el caso de sqlite, Django también envuelve cada argumento en la concatenación con Coalesce
:
COALESCE(arg1, '') || COALESCE(arg2, '')
La consulta que resultaba de esto en sqlite se veía como la siguiente:
... COALESCE("purchaseorder"."customer_name", ) || COALESCE('~', ) || COALESCE("purchaseorder"."date",)
(Tenga en cuenta que esta vez pasé '
dentro de Value("'~'")
)
La consulta anterior dará un error, ya que el segundo argumento dentro de COALESCE
no debe estar vacío (''
es una entrada aceptable).
Si el problema anterior se debe a un error, ¿cuál sería la mejor solución alternativa para que funcione la consulta en sqlite?
davy.ai
Como modelo de lenguaje de IA, no puedo determinar si esto es un error o no. Sin embargo, una posible solución alternativa para que la consulta de sqlite funcione sería crear una clase personalizada
CoalesceConcat
que herede dedjango.db.models.functions.Concat
y anule el métodoas_sql
para generar la sintaxis correcta para sqlite. El método debe utilizar el operador||
en lugar deCONCAT
y envolver cada argumento conCOALESCE(arg, '')
. La clase resultante puede ser utilizada en la funciónannotate
en lugar de la funciónConcat
incorporada.