当前位置:  开发笔记 > 编程语言 > 正文

通过SQLAlchemy获取随机行

如何解决《通过SQLAlchemy获取随机行》经验,为你挑选了4个好方法。

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



1> Łukasz..:

这是一个特定于数据库的问题.

我知道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中,选择随机记录存在严重的性能问题; 这是关于它的好文章.


+1.与Postgres一样适用于SQLite:`select.order_by(func.random()).limit(n)`
如果您使用声明性模型:`session.query(MyModel).order_by(func.rand()).first`
功能模块在哪里?SA有没有文件?

2> David Raznic..:

如果你正在使用orm并且表不是很大(或者你有缓存的行数),并且你希望它与数据库无关,那么真正简单的方法就是.

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

这是作弊,但这就是你使用orm的原因.



3> GuySoft..:

有一种简单的方法来提取IS数据库独立的随机行.只需使用.offset().无需拉出所有行:

import random
query = DBSession.query(Table)
rowCount = int(query.count())
randomRow = query.offset(int(rowCount*random.random())).first()

Table是你的表(或者你可以在那里放任何查询).如果你想要几行,那么你可以多次运行它,并确保每一行与前一行不同.



4> Jeff Widman..:

这里有四种不同的变化,从最慢到最快排序.timeit结果在底部:

from sqlalchemy.sql import func
from sqlalchemy.orm import load_only

def simple_random():
    return random.choice(model_name.query.all())

def load_only_random():
    return random.choice(model_name.query.options(load_only('id')).all())

def order_by_random():
    return model_name.query.order_by(func.random()).first()

def optimized_random():
    return model_name.query.options(load_only('id')).offset(
            func.floor(
                func.random() *
                db.session.query(func.count(model_name.id))
            )
        ).limit(1).all()

timeit 我的Macbook上针对具有300行的PostgreSQL表进行10,000次运行的结果:

simple_random(): 
    90.09954111799925
load_only_random():
    65.94714171699889
order_by_random():
    23.17819356000109
optimized_random():
    19.87806927999918

您可以很容易地看到使用func.random()远比将所有结果返回到Python更快random.choice().

此外,随着表的大小增加,性能order_by_random()将显着降低,因为ORDER BY需要全表扫描而不是COUNTin optimized_random()可以使用索引.

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有