Как запросить базу данных по идентификатору с помощью SqlAlchemy?

95

Мне нужно запросить базу данных SQLAlchemy idчем-то похожим на

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

но для id. Как мне это сделать? [Поиск в Google и SO не помог]

Oerd
источник
Пожалуйста, предоставьте более подробную информацию, например, эквивалентный SQL или псевдокод, делающий то, что вы хотите. Что такое «идентификатор базы данных SQLAlchemy»?
Daniel Kluev
Есть ли в вашей таблице столбец идентификаторов?
Кейт

Ответы:

130

В запросе есть функция получения, которая поддерживает запросы по первичному ключу таблицы, как я предполагаю id.

Например, чтобы запросить объект с ID 23:

User.query.get(23)

Примечание. Как уже упоминалось несколькими другими комментаторами и ответами, это не просто сокращение для «Выполнить фильтрацию запроса по первичному ключу». В зависимости от состояния сеанса SQLAlchemy запуск этого кода может запросить базу данных и вернуть новый экземпляр, или он может вернуть экземпляр объекта, запрошенного ранее в вашем коде, без фактического запроса базы данных. Если вы еще этого не сделали, подумайте о прочтении документации по сеансу SQLAlchemy, чтобы понять последствия.

Марк Хилдрет
источник
8
Get функция также поддерживает несколько первичных ключей: YourModel.query.get((pk1, pk2)). Обратите внимание на кортеж.
marc_aragones 01
3
В get()функции запросов объектов по первичному ключу. Если вы хотите запросить id, вы должны idсначала установить в качестве первичного ключа.
46

Вы можете запросить пользователя с id = 1 следующим образом

session.query(User).get(1)

peggygao1988
источник
7

get () иногда не соответствует вашим ожиданиям:

если ваша транзакция была совершена:

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

если вы находитесь в транзакции (get () предоставит вам объект результата в памяти без запроса базы данных):

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

лучше использовать это:

>>> 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',)
панда912
источник
1
Чем такое неожиданное поведение?
Соломон Учко
Я имею в виду, что если вы находитесь в транзакции (еще не сеансе.commit), get()кажется, что вы получите объект результата в памяти (без фактического запроса базы данных), но filter().first()всегда будет запрашивать базу данных.
panda912
Возможно ли одновременное изменение базы данных во время транзакции? Если нет, то getлучше использовать за счет увеличения эффективности.
Соломон Учко
1
поскольку я знаю, что sqlalchemy не может работать с асинхронным материалом (кажется, только с gevent), и да, getэто более эффективно.
panda912
Почему .first () отличается от .get () в том, что касается транзакции? Всегда ли .first () возвращается в базу данных? Это то, что .get () сначала просматривает текущий env, чтобы узнать, знает ли он этот идентификатор или что-то в этом роде?
msouth
1

Если вы используете tables reflection вас могут возникнуть проблемы с приведенными решениями. (Предыдущие решения здесь не работали для меня).

В итоге я использовал:

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

( objectбыл получен путем отражения из базы данных, поэтому вам нужно использовать.__class__ )

Надеюсь, это поможет.

октаэдро
источник
0

Во-первых, вы должны установить idв качестве первичного ключа.
Затем вы можете использовать этот query.get()метод для запроса объектов, по idкоторым уже есть первичный ключ.

Поскольку query.get()метод запроса объектов по первичному ключу.
Получено из документации 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)
Джастин Ли
источник