【问题标题】:Find place number in queue, peewee producing an illegal sqlite3 query在队列中查找位置编号,peewee 产生非法 sqlite3 查询
【发布时间】:2019-08-10 23:31:38
【问题描述】:

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

我尝试过分离成更多的子查询,查看了 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

【问题讨论】:

    标签: python sqlite peewee row-number


    【解决方案1】:

    我没有看到任何直接的问题,除了你可以检查你的 sqlite 版本。窗口函数是相对较新的添加,您需要 3.25.0 或更高版本。

    import sqlite3
    sqlite3.sqlite_version
    

    【讨论】:

    • 我的 .exe 说 3.29.0,而 Python 控制台(在 Pycharm 中)说 3.21.0 :\
    • 这很可能,我得进一步调查。谢谢。
    • 似乎没有好的解决方案。我必须将 Python 更新到最新版本 3.7.4 才能获得 sqlite 3.28.0,或者使用看起来效率很低的 hack:exh. 1exh .2
    • 最终将 Python 升级到 3.7.4。
    • 没必要。您始终可以编译 sqlite 并在系统范围内安装它,或者构建静态链接的 sqlite3 驱动程序:charlesleifer.com/blog/…
    猜你喜欢
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 2021-09-23
    • 2018-04-25
    • 2014-04-13
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    相关资源
    最近更新 更多