通过SQLAlchemy获取随机行

时间:2020-03-05 18:52:48  来源:igfitidea点击:

如何使用SQLAlchemy从表中选择一个(或者一些)随机行?

解决方案

回答

通过SQL有几种方法,具体取决于所使用的数据库。

(我认为SQLAlchemy仍然可以使用所有这些方法)

MySQL的:

SELECT colum FROM table
ORDER BY RAND()
LIMIT 1

PostgreSQL:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1

MSSQL:

SELECT TOP 1 column FROM table
ORDER BY NEWID()

IBM DB2:

SELECT column, RAND() as IDX
FROM table
ORDER BY IDX FETCH FIRST 1 ROWS ONLY

甲骨文:

SELECT column FROM
(SELECT column FROM table
ORDER BY dbms_random.value)
WHERE rownum = 1

但是我不知道任何标准方法

回答

这在很大程度上是特定于数据库的问题。

我知道PostgreSQL,SQLite,MySQL和Oracle可以通过随机函数进行排序,因此可以在SQLAlchemy中使用它:

from  sqlalchemy.sql.expression import func, select

select.order_by(func.random()) # for PostgreSQL, SQLite

select.order_by(func.rand()) # for MySQL

select.order_by('dbms_random.value') # For Oracle

接下来,我们需要通过所需的记录数来限制查询(例如,使用.limit())。

请记住,至少在PostgreSQL中,选择随机记录会带来严重的性能问题。这是一篇很好的文章。

回答

如果我们使用的是orm且表不大(或者我们已缓存其行数),并且希望它独立于数据库,那么真正简单的方法就是。

import random
rand = random.randrange(0, session.query(Table).count()) 
row = session.query(Table)[rand]

这有点作弊,但这就是为什么要使用orm的原因。

回答

Lukasz示例的增强版本,如果我们需要随机选择多行:

import random

# you must first select all the values of the primary key field for the table.
# in some particular cases you can use xrange(session.query(Table).count()) instead
ids = session.query(Table.primary_key_field).all() 
ids_sample = random.sample(ids, 100)

rows = session.query(Table).filter(Table.primary_key_field.in_(ids_sample))

因此,这篇文章只是指出我们可以使用.in_同时选择多个字段。