Як запитувати базу даних за ідентифікатором за допомогою 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.