¿Cómo consultar la base de datos por id usando SqlAlchemy?

95

Necesito consultar una base de datos SQLAlchemy por idalgo similar a

User.query.filter_by (nombre de usuario = 'peter')

pero para id. ¿Cómo hago esto? [Buscar en Google y SO no ayudó]

Oerd
fuente
Proporcione más detalles, como SQL equivalente o pseudocódigo haciendo lo que desee. ¿Qué es el "ID de la base de datos de SQLAlchemy"?
Daniel Kluev
¿Su tabla tiene una columna de identificación?
Keith

Respuestas:

130

Query tiene una función de obtención que admite consultas mediante la clave principal de la tabla, que supongo que sí id.

Por ejemplo, para consultar un objeto con ID de 23:

User.query.get(23)

Nota: Como han mencionado algunos otros comentaristas y respuestas, esto no es simplemente una abreviatura de "Realizar un filtrado de consultas en la clave principal". Dependiendo del estado de la sesión de SQLAlchemy, ejecutar este código puede consultar la base de datos y devolver una nueva instancia, o puede devolver una instancia de un objeto consultado anteriormente en su código sin consultar realmente la base de datos. Si aún no lo ha hecho, considere leer la documentación sobre la sesión de SQLAlchemy para comprender las ramificaciones.

Mark Hildreth
fuente
8
Get función también es compatible con múltiples claves primarias: YourModel.query.get((pk1, pk2)). Observe la tupla.
marc_aragones
3
La get()función consulta objetos por clave primaria. Si desea realizar una consulta id, idprimero debe establecerla como clave principal.
46

Puede consultar a un usuario con id = 1 como este

session.query(User).get(1)

peggygao1988
fuente
7

get () no es como esperabas a veces:

si su transacción se realizó:

>>> session.query(User).get(1)
[SQL]: BEGIN (implicit)
[SQL]: SELECT user.id AS user_id, user.name AS user_name, user.fullname AS user_fullname
FROM user
WHERE user.id = ?
[SQL]: (1,)
<User(u'ed', u'Ed Jones')>

si está en una transacción (get () le dará el objeto de resultado en la memoria sin consultar la base de datos):

>>> session.query(User).get(1)
<User(u'ed', u'Ed Jones')>

mejor usar esto:

>>> session.query(User.name).filter(User.id == 1).first()
[SQL]: SELECT user.name AS user_name
FROM user
WHERE user.id = ?
 LIMIT ? OFFSET ?
[SQL]: (1, 1, 0)
(u'Edwardo',)
panda912
fuente
1
¿Cómo es este comportamiento inesperado?
Solomon Ucko
Quiero decir, si usted está en una transacción (no session.commit todavía), get()parece darle el objeto de resultado en la memoria (sin consultar realmente la base de datos), pero filter().first()siempre consultará la base de datos.
panda912
¿Es posible cambiar simultáneamente la base de datos durante la transacción? Si no es así, getes mejor usarlo debido al aumento de la eficiencia.
Solomon Ucko
1
como sé, sqlalchemy no puede funcionar con las cosas asincrónicas (parece solo con gevent), y sí, getes más eficiente.
panda912
¿Por qué .first () es diferente de .get () en lo que respecta a la transacción? ¿.First () siempre vuelve a la base de datos? ¿Es que .get () busca primero en el entorno actual para ver si conoce esa identificación o algo así?
msouth
1

Si lo usa tables reflection, puede tener problemas con las soluciones proporcionadas. (Las soluciones anteriores aquí no funcionaron para mí).

Lo que terminé usando fue:

session.query(object._class_).get(id)

( objectse recuperó por reflexión de la base de datos, es por eso que debe usar .__class__)

Espero que esto ayude.

octaedro
fuente
0

Primero, debe establecer idcomo clave principal.
Luego, podría usar el query.get()método para consultar objetos por los idque ya es la clave principal.

Desde el query.get()método para consultar objetos por clave primaria.
Inferido de la documentación de Flask-SQLAlchemy

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy()
db.init_app(app)

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)

def test():
    id = 1
    user = User.query.get(id)
Justin Lee
fuente