簡體   English   中英

Django Queryset 過濾器缺少引號

[英]Django Queryset Filter Missing Quotes

我有一個列表,當在外部表的非主鍵“test”中找到任何這些項目時,我想過濾我的查詢集。 所以我寫了這樣的東西:

test_list = ['test1', 'test2', 'test3', 'test4', 'test5']
return cls.objects.filter(reduce(lambda x, y: x | y, [models.Q(next_task__test = item) for item in test_list]))[:20]

這將返回一個空列表。 當我查看它生成的 SQL 查詢時,我得到:

SELECT ...
FROM ...
WHERE "job"."next_task_id" IN (test1, test2, test3, test4, test5) LIMIT 20;

而它應該是這樣的:

SELECT ...
FROM ...
WHERE "job"."next_task_id" IN ('test1', 'test2', 'test3', 'test4', 'test5') LIMIT 20;

如果沒有引號,SQLite3 認為這些是列名,並且不返回任何內容。 當我手動添加引號並在完全沒有 Django 的表上執行 SQLite3 查詢時,我得到了想要的結果。 如何讓 Django 正確發出查詢?

這個問題很有趣,它似乎只發生在 SQLite 中。 它在這里是已知的: https : //code.djangoproject.com/ticket/14091docs

所以基本上查詢可能沒有錯,但是當您使用 Django 返回查詢時,它看起來是錯誤的:

>>> test_list = ['test1', 'test2', 'test3', 'test4', 'test5']
>>> cls.objects.filter(next_task__test__in=test_list).query.__str__()

SELECT ...
FROM ...
WHERE "job"."next_task_id" IN (test1, test2, test3, test4, test5);

解決方法:如果您確實認為查詢是錯誤的,則為列表提供更多引用,例如:

>>> test_list = ["'test1'", "'test2'", "'test3'", "'test4'", "'test5'"]
>>> cls.objects.filter(next_task__test__in=test_list).query.__str__()

SELECT ...
FROM ...
WHERE "job"."next_task_id" IN ('test1', 'test2', 'test3', 'test4', 'test5');

無論如何,我都會依賴標准的,上面的工作太黑了。

我真的很喜歡@Andrey-St 的回答,但一位同事指出,這需要往返數據庫來完成這項工作。 因此,我們將其更改為僅從游標中獲取格式化查詢。

 def stringify_queryset(qs):
     sql, params = qs.query.sql_with_params()
     with connection.cursor() as cursor:
         return cursor.mogrify(sql, params)

(我們將 psycopg2 用於 Postgres——我不確定mogrify()在其他數據庫引擎上是否可用)。

def stringify_queryset(qs: QuerySet) -> str:
    sql, params = qs.query.sql_with_params()
    with connection.cursor() as cursor:
        cursor.execute('EXPLAIN ' + sql, params)
        raw_sql =  cursor.db.ops.last_executed_query(cursor, sql, params)
    raw_sql = raw_sql[len('EXPLAIN '):]
    return raw_sql

(取自https://code.djangoproject.com/ticket/17741

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM