在队列中查找位置编号,peewee 生成非法的 sqlite3 查询

Find place number in queue, peewee producing an illegal sqlite3 query

我正在尝试查找队列中一张票的位置编号。在 sqlite3 查询失败,给出的错误很奇特:sqlite3.OperationalError: near "(": syntax error。我似乎不明白列引用是如何使用的。

我试过分成更多的子查询,查看了无数聚合使用的例子,window 函数等,在 peewee、sqlite 和 MySQL 中。我没有找到的是 peewee 中 fn.ROW_NUMBER 的示例。我检查了多个网站的查询,他们会重复同样的错误。

peewee 生成的查询:

SELECT ROW_NUMBER() OVER (ORDER BY "t1"."ordinal") AS ordinal_index 
FROM "dbticket" AS t1 
WHERE (((("t1"."called_at" IS ?) AND ("t1"."abandoned_at" IS ?)) AND ("t1"."removed_at" IS ?)) AND ("ticket_id" = ?))

参数:

[None, None, None, 'red-shibe'

造成这个地狱的代码:

from pathlib import Path
import os
THIS_FOLDER = Path(os.path.dirname(os.path.abspath(__file__)))
db_file = THIS_FOLDER / 'queue.db'
sqlite_db = SqliteDatabase(str(db_file), pragmas=[('journal_mode', 'wal')])



class DBTicket(BaseModel):
    ordinal = PrimaryKeyAutoIncrementField()
    ticket_id = TextField(unique=True)
    queue_name = TextField()

    initiated_at = DateTimeField(default=datetime.utcnow)
    called_at = DateTimeField(null=True)
    abandoned_at = DateTimeField(null=True)
    removed_at = DateTimeField(null=True)

    def __str__(self):
        return f'{self.ordinal}:{self.ticket_id}'

in_queue_predicate = (DBTicket.called_at.is_null() &
                      DBTicket.abandoned_at.is_null() &
                      DBTicket.removed_at.is_null())

def ticket_place_number(ticket_id):
    queue = DBTicket.select() \
                    .where(in_queue_predicate)
    place_number = queue.select(fn.ROW_NUMBER().over(order_by=[DBTicket.ordinal]).alias('ordinal_index')) \
                        .where(queue.c.ticket_id == ticket_id) \
                        .scalar()
    return place_number

我没有发现任何直接问题,除此之外您可以检查您的 sqlite 版本。 Window 函数是最近才添加的,您需要 3.25.0 或更新版本。

import sqlite3
sqlite3.sqlite_version