如何将行号列添加到 SqlAlchemy 查询?

jpm*_*rin 3 python mysql sqlalchemy

我想将行号作为我的查询列。由于我使用的是 MySql,我无法使用func.row_number()SqlAlchemy的内置功能。此查询的结果将被分页,因此我想在拆分发生之前保留行号。

session.query(MyModel.id, MyModel.date, "row_number")
Run Code Online (Sandbox Code Playgroud)

我尝试使用 anhybrid_property来增加MyModel我在查询之前重置的类内部的静态变量,但它没有用。

@hybrid_property
def row_number(self):
    cls = self.__class__
    cls.row_index = cls.row_index + 1
    return literal(self.row_index)

@row_number.expression
def row_number(cls):
    cls.row_index = cls.row_index + 1
    return literal(cls.row_index)
Run Code Online (Sandbox Code Playgroud)

我还尝试将子查询与此解决方案混合使用:

 session.query(myquery.subquery(), literal("@rownum := @rownum + 1 AS row_number"))
Run Code Online (Sandbox Code Playgroud)

但是我没有找到一种方法来为(SELECT @rownum := 0) r.

有什么建议?

编辑

目前,我正在循环分页查询的结果,并将从当前页面计算出的数字分配给每一行。

Jas*_*n S 5

SQLAlchemy 允许您text()在某些地方使用,但不能随意使用。我特别找不到在列或连接中使用它的简单/记录的方法。但是,您可以用 SQL 编写整个查询,并且仍然可以从中获取 ORM 对象。例子:

query = session.query(Foobar, "rownum")
query = query.from_statement(
    "select foobar.*, cast(@row := @row + 1 as unsigned) as rownum"
    " from foobar, (select @row := 0) as init"
    )
Run Code Online (Sandbox Code Playgroud)

话虽如此,我也没有真正看到类似的问题enumerate(query.all())。请注意,如果您使用LIMIT表达式,您从 MySQL 获得的行号将用于最终结果,并且仍需要添加页面起始索引。也就是说,默认情况下它不是“拆分之前”。如果您想在 MySQL 中为您添加起始行,您可以执行以下操作:

prevrow = 42
query = session.query(Foobar, "rownum")
query = query.from_statement(sqlalchemy.text(
    "select foobar.*, cast(@row := @row + 1 as unsigned) as rownum"
    " from foobar, (select @row := :prevrow) as init"
    ).bindparams(prevrow=prevrow))
Run Code Online (Sandbox Code Playgroud)

在这种情况下,数字将从 43 开始,因为它是预先递增的。