variable usar randint números numeros numero imprimir generar funciones enteros elegir como azar aleatorios aleatorio aleatoria python sql database sqlalchemy

python - usar - Obteniendo una fila aleatoria a través de SQLAlchemy



python funciones random (8)

Hay un par de maneras a través de SQL, dependiendo de qué base de datos se está utilizando.

(Creo que SQLAlchemy puede usar todos estos de todos modos)

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

Oráculo:

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

Sin embargo, no sé de ninguna manera estándar

¿Cómo selecciono una (o algunas) filas aleatorias de una tabla usando SQLAlchemy?


Si está utilizando el orm y la tabla no es grande (o tiene la cantidad de filas en caché) y desea que sea independiente de la base de datos, el enfoque realmente simple es.

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

Esto es hacer trampa un poco, pero es por eso que usas un orm.


Una versión mejorada del ejemplo de Lukasz, en el caso de que necesite seleccionar varias filas al azar:

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))

Por lo tanto, esta publicación es solo para señalar que puede usar .in_ para seleccionar varios campos al mismo tiempo.


Esto es en gran medida un problema específico de la base de datos.

Sé que PostgreSQL y MySQL tienen la capacidad de ordenar por una función aleatoria, por lo que puede usar esto en 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

A continuación, debe limitar la consulta por la cantidad de registros que necesita (por ejemplo, utilizando .limit() ).

Tenga en cuenta que al menos en PostgreSQL, la selección de registros aleatorios tiene graves problemas de rendimiento; aquí hay un buen artículo al respecto.


Hay una forma simple de extraer una fila aleatoria que IS sea independiente de la base de datos. Solo usa .offset (). No es necesario tirar de todas las filas:

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

Donde Table es su tabla (o puede poner cualquier consulta allí). Si quiere algunas filas, puede ejecutar esto varias veces y asegurarse de que cada fila no sea idéntica a la anterior.


esta solución seleccionará una sola fila aleatoria

Esta solución requiere que la clave principal se denomine id, debería ser si aún no lo está:

import random max_model_id = YourModel.query.order_by(YourModel.id.desc())[0].id random_id = random.randrange(0,max_model_id) random_row = YourModel.query.get(random_id) print random_row


Aquí hay cuatro variaciones diferentes, ordenadas de la más lenta a la más rápida. timeit resultados de tiempo en la parte inferior:

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 resulta para 10,000 carreras en mi Macbook contra una tabla de PostgreSQL con 300 filas:

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

Puede ver fácilmente que usar func.random() es mucho más rápido que devolver todos los resultados a func.random() de Python.

Además, a medida que aumenta el tamaño de la tabla, el rendimiento de order_by_random() se degradará significativamente porque un ORDER BY requiere una exploración de tabla completa frente a COUNT en optimized_random() puede usar un índice.


Esta es la solución que uso:

from random import randint rows_query = session.query(Table) # get all rows if rows_query.count() > 0: # make sure there''s at least 1 row rand_index = randint(0,rows_query.count()-1) # get random index to rows rand_row = rows_query.all()[rand_index] # use random index to get random row