Veritabanını SqlAlchemy kullanarak kimliğe göre nasıl sorgulayabilirim?


95

Bir SQLAlchemy veritabanını aşağıdakine idbenzer bir şeyle sorgulamam gerekiyor

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

ama id için. Bunu nasıl yaparım? [Google ve SO üzerinden arama yapmak yardımcı olmadı]


Lütfen eşdeğer SQL veya istediğinizi yapan sözde kod gibi daha fazla ayrıntı sağlayın. "SQLAlchemy veritabanı kimliği" nedir?
Daniel Kluev

Tablonuzda bir kimlik sütunu var mı?
Keith

Yanıtlar:


130

Sorgu, tablonun birincil anahtarıyla sorgulamayı destekleyen bir get işlevine sahiptir, ki öyle olduğunu varsayıyorum id.

Örneğin, kimliği 23 olan bir nesneyi sorgulamak için:

User.query.get(23)

Not: Birkaç başka yorumcu ve yanıtın da belirttiği gibi, bu sadece "Birincil anahtarda bir sorgu filtrelemesi gerçekleştirin" için bir kısaltma değildir. SQLAlchemy oturumunun durumuna bağlı olarak, bu kodu çalıştırmak veritabanını sorgulayabilir ve yeni bir örnek döndürebilir veya veritabanını gerçekten sorgulamadan kodunuzda daha önce sorgulanan bir nesnenin örneğini döndürebilir. Henüz yapmadıysanız , sonuçlarını anlamak için SQLAlchemy Oturumundaki belgeleri okumayı düşünün .


8
Al fonksiyonu aynı zamanda birden fazla birincil anahtarlarını destekler: YourModel.query.get((pk1, pk2)). Demire dikkat edin.
marc_aragones

3
get()Fonksiyon sorgular primer anahtar tarafından nesneleri. İle sorgulamak idisterseniz, idönce birincil anahtar olarak ayarlamalısınız .

46

İd = 1 olan bir Kullanıcıyı bunun gibi sorgulayabilirsiniz

session.query(User).get(1)


7

get () bazen beklediğiniz gibi olmayabilir:

işleminiz yapıldıysa:

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

bir işlem içindeyseniz (get (), veritabanını sorgulamadan size bellekteki sonuç nesnesini verecektir):

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

bunu kullanmak daha iyi:

>>> 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
Bu davranış nasıl beklenmedik?
Solomon Ucko

Demek istediğim, eğer bir işlemde iseniz (henüz session.commit değil) get()size bellekte sonuç nesnesini veriyor gibi görünüyor (veritabanını gerçekten sorgulamadan), ancak filter().first()her zaman veritabanını sorgulayacaktır.
panda912

İşlem sırasında veri tabanını eşzamanlı değiştirmek mümkün müdür? Değilse, getverimlilik artışı nedeniyle kullanmak daha iyidir.
Solomon Ucko

1
bildiğim gibi sqlalchemy zaman uyumsuz şeylerle çalışamaz (sadece gevent ile görünür) ve evet, getdaha verimli.
panda912

İşlem söz konusu olduğunda .first (), .get () 'den neden farklı? .First () her zaman veritabanına geri mi döner? Bu .get (), o kimliği veya başka bir şeyi bilip bilmediğini görmek için önce mevcut ortamın içine bakar mı?
msouth

1

Eğer kullanırsanız tables reflection, verilen çözümlerle ilgili sorunlarınız olabilir. (Buradaki önceki çözümler benim için işe yaramadı).

Kullanmaya son verdiğim şey şuydu:

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

( objectveritabanından yansıma yoluyla alındı, bu nedenle kullanmanız gerekir.__class__ )

Umarım bu yardımcı olur.


0

İlk idolarak, birincil anahtar olarak ayarlamalısınız .
Daha sonra , zaten birincil anahtar olan query.get()nesneleri sorgulamak için yöntemi kullanabilirsiniz id.

Yana query.get()sorguya yöntem, primer anahtar tarafından nesneleri.
Olayla Flask-SQLAlchemy belgelerinde

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.