Como consultar o banco de dados por id usando SqlAlchemy?

95

Eu preciso consultar um banco de dados SQLAlchemy por idalgo semelhante a

User.query.filter_by (username = 'peter')

mas para id. Como eu faço isso? [Pesquisar no Google e no SO não ajudou]

Oerd
fonte
Forneça mais detalhes, como SQL equivalente ou pseudocódigo fazendo o que você deseja. O que é "ID do banco de dados SQLAlchemy"?
Daniel Kluev
A sua tabela tem uma coluna id?
Keith de

Respostas:

130

Query tem uma função get que oferece suporte a consultas pela chave primária da tabela, o que presumo que idseja.

Por exemplo, para consultar um objeto com ID 23:

User.query.get(23)

Observação: como alguns outros comentaristas e respostas mencionaram, isso não é simplesmente uma abreviatura para "Executar uma filtragem de consulta na chave primária". Dependendo do estado da sessão SQLAlchemy, a execução deste código pode consultar o banco de dados e retornar uma nova instância ou pode retornar uma instância de um objeto consultado anteriormente em seu código sem realmente consultar o banco de dados. Se ainda não o fez, considere a leitura da documentação na Sessão SQLAlchemy para entender as ramificações.

Mark Hildreth
fonte
8
Função get também suporta múltiplas chaves primárias: YourModel.query.get((pk1, pk2)). Observe a tupla.
marc_aragones 01 de
3
A get()função consulta objetos por chave primária. Se você gostaria de consultar por id, deve primeiro definir idcomo chave primária.
46

Você pode consultar um usuário com id = 1 como este

session.query(User).get(1)

peggygao1988
fonte
7

get () não é o esperado às vezes:

se sua transação foi feita:

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

se você estiver em uma transação (get () fornecerá o objeto de resultado na memória sem consultar o banco de dados):

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

melhor usar isso:

>>> 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
fonte
1
Como esse comportamento é inesperado?
Solomon Ucko de
Quero dizer, se você em uma transação (não em session.commit ainda), o get()parece dar-lhe o objeto de resultado na memória (sem realmente consultar o banco de dados), mas filter().first()sempre consultará o banco de dados.
panda912
É possível alterar simultaneamente o banco de dados durante a transação? Caso contrário, o uso geté melhor devido ao aumento da eficiência.
Solomon Ucko
1
como eu sei o sqlalchemy não pode funcionar com o material assíncrono (parece apenas com gevent), e sim, geté mais eficiente.
panda912
Por que .first () é diferente de .get () no que diz respeito à transação? .First () sempre volta para o banco de dados? É que .get () procura no env atual primeiro para ver se ele conhece aquele id ou algo assim?
msouth de
1

Se você usar, tables reflectionpoderá ter problemas com as soluções fornecidas. (As soluções anteriores aqui não funcionaram para mim).

O que acabei usando foi:

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

( objectfoi recuperado por reflexão do banco de dados, é por isso que você precisa usar .__class__)

Eu espero que isso ajude.

octaedro
fonte
0

Primeiro, você deve definir idcomo a chave primária.
Então você poderia usar o query.get()método para consultar objetos pelos idquais já é a chave primária.

Desde o query.get()método para consultar objetos pela chave primária.
Inferido da documentação 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
fonte