Consulta de Flask SQLAlchemy, especificar nombres de columna


126

¿Cómo especifico la columna que quiero en mi consulta usando un modelo (selecciona todas las columnas por defecto)? Sé cómo hacer esto con la sesión sqlalchmey:, session.query(self.col1)pero ¿cómo lo hago con modelos? No puedo hacerlo SomeModel.query(). ¿Hay alguna manera?

Respuestas:


221

Puede utilizar el with_entities()método para restringir las columnas que le gustaría devolver en el resultado. ( documentación )

result = SomeModel.query.with_entities(SomeModel.col1, SomeModel.col2)

Dependiendo de sus requisitos, también puede encontrar útiles los aplazamientos . Le permiten devolver el objeto completo pero restringen las columnas que pasan por el cable.


21
with_entities () hace que all () produzca tuplas de valores de columna, ¡no objetos!
kolypto

10
kolypto: Cede todo lo que le pides que ceda. SomeModel.query.with_entities (SomeModel) produciría el objeto. Al igual que session.query (SomeModel.col1, SomeModel.col2) produciría tuplas de valores de columna. Los diferidos son lo que usaría si no desea que las columnas pasen por el cable, pero desea el objeto completo de todos modos.
David McKeone

2
Gracias funciona. Pero, ¿cómo podríamos asignar un alias al campo? Porque en mi caso, estoy usando JOIN y el IDcampo de conflicto que está presente en ambas tablas
Mitul Shah

Sí, tengo la misma pregunta con @MitulShah, ¿cómo establecer un alias?
Nam G VU

Para el alias, vea esta breve respuesta a continuación, es decir. use .label() stackoverflow.com/a/11535992/248616
Nam G VU

69
session.query().with_entities(SomeModel.col1)

es lo mismo que

session.query(SomeModel.col1)

para alias, podemos usar .label ()

session.query(SomeModel.col1.label('some alias name'))

2
El segundo suena más lógico y es más corto - ganar / ganar
fgblomqvist

7
Tu primera afirmación es incorrecta. Necesita paréntesis. Entonces, debería leer:session.query().with_entities(SomeModel.col1)
JGFMK

La primera (y tercera) opciones son las mejores, con diferencia, si desea reutilizar objetos de consulta existentes, especialmente en el caso de realizar múltiples subconsultas complejas.
Jamie Strauss

36

Puede usar la función load_only :

from sqlalchemy.orm import load_only

fields = ['name', 'addr', 'phone', 'url']
companies = session.query(SomeModel).options(load_only(*fields)).all()

1
Esta solución es la mejor ya que sigue funcionando como un Objeto, no solo como la lista de resultados.
rborodinov

Felicitaciones por esta solución. Tiene muchas ventajas: - devuelve exactamente el mismo tipo de objeto que .first()y .one()(que cargará campos y relaciones perezosos / ansiosos), - se puede configurar como componente de consulta
Damien

el código está limpio pero la consulta SQL selecciona todos los campos de la base de datos. He utilizado with_entitiescomo se indica en la respuesta aceptada y la consulta seleccionó solo esos campos /.
Srikanth Jeeva

11

Puede usar Model.query, porque Modelse asigna (o generalmente su clase base, especialmente en los casos en que se usa la extensión declarativa) Sesssion.query_property. En este caso el Model.queryes equivalente aSession.query(Model) .

No conozco la forma de modificar las columnas devueltas por la consulta (excepto agregando más uso add_columns()).
Entonces, tu mejor oportunidad es usar el Session.query(Model.col1, Model.col2, ...)(como ya lo mostró Salil).


Creo que también puede haber una manera de hacer esto con una lista de columnas para valores de consulta (), docs.sqlalchemy.org/en/latest/orm/… - pero el azúcar sintáctico de la lista se me escapa en este momento.
JGFMK


-11

Un ejemplo aquí:

movies = Movie.query.filter(Movie.rating != 0).order_by(desc(Movie.rating)).all()

Busco en la base de datos películas con calificación <> 0, y luego las ordeno primero por calificación con la calificación más alta.

Eche un vistazo aquí: Seleccionar, Insertar, Eliminar en Flask-SQLAlchemy

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.