Як запитувати базу даних за ідентифікатором за допомогою SqlAlchemy?


95

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

User.query.filter_by (ім'я користувача = 'peter')

але для ідентифікатора. Як це зробити? [Пошук у Google та SO не допомогли]


Будь ласка, надайте більше деталей, наприклад еквівалентний SQL або псевдокод, виконуючи те, що ви хочете. Що таке "ідентифікатор бази даних SQLAlchemy"?
Даніель Клюєв,

У вашій таблиці є стовпець ідентифікатора?
Кіт,

Відповіді:


130

Запит має функцію get, яка підтримує запити за допомогою первинного ключа таблиці, що, я припускаю, idє.

Наприклад, для запиту об’єкта з ідентифікатором 23:

User.query.get(23)

Примітка. Як зазначали деякі інші коментатори та відповіді, це не просто скорочення "Виконати фільтрацію запитів за первинним ключем". Залежно від стану сеансу SQLAlchemy, запуск цього коду може запитати базу даних і повернути новий екземпляр, або він може повернути екземпляр об’єкта, запитуваного раніше у вашому коді, фактично не запитуючи базу даних. Якщо ви цього ще не зробили, розгляньте документацію на сеансі SQLAlchemy, щоб зрозуміти наслідки.


8
Get функція також підтримує кілька первинних ключів: YourModel.query.get((pk1, pk2)). Зверніть увагу на кортеж.
marc_aragones

3
У get()функції запитів об'єктів по первинному ключу. Якщо ви хочете здійснити запит id, idспершу встановіть як первинний ключ.

46

Ви можете запитати Користувача з id = 1 таким чином

session.query(User).get(1)


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

1
Як така поведінка несподівана?
Соломон Уцко

Я маю на увазі, якщо ви в транзакції (поки не session.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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.