Perbedaan antara filter dan filter_by dalam SQLAlchemy


304

Adakah yang bisa menjelaskan perbedaan antara filterdan filter_byfungsi dalam SQLAlchemy? Yang mana yang harus saya gunakan?

Jawaban:


393

filter_by digunakan untuk pertanyaan sederhana pada nama kolom menggunakan kwarg biasa, seperti

db.users.filter_by(name='Joe')

Hal yang sama dapat dilakukan dengan filter, tidak menggunakan kwargs, melainkan menggunakan operator persamaan '==', yang telah kelebihan beban pada objek db.users.name:

db.users.filter(db.users.name=='Joe')

Anda juga dapat menulis kueri yang lebih kuat menggunakan filter, seperti ekspresi seperti:

db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))


22
Bagaimana cara kerjanya di bawah tenda? Tidak akan db.users.name=='Ryan'mengevaluasi sekali ke konstanta dan kemudian menjadi tidak berarti sejak saat itu? Sepertinya orang perlu menggunakan lambda agar ini berfungsi.
Hamish Grubijan

46
operator kesetaraan kelebihan beban
Daniel Velkov

9
type(model.column_name == 'asdf')sqlalchemy.sql.elements.BinaryExpression
Nick T

11
Hati-hati saat menggunakan .filter. kueri seperti id=12345, query(users).filter(id == id)tidak akan difilter users.id. Sebaliknya, ia akan mengevaluasi id == idsebagai Truedan mengembalikan semua pengguna. Anda perlu menggunakan .filter(users.id == id)(seperti yang ditunjukkan di atas). Saya membuat kesalahan ini sebelumnya hari ini.
Nico Cernek

118

Kami sebenarnya menggabungkan ini bersama-sama pada awalnya, yaitu ada metode "filter" yang diterima *argsdan **kwargs, di mana Anda dapat menyampaikan argumen SQL atau argumen kata kunci (atau keduanya). Sebenarnya saya merasa jauh lebih nyaman, tetapi orang-orang selalu bingung karenanya, karena mereka biasanya masih bisa mengatasi perbedaan antara column == expressiondan keyword = expression. Jadi kami membaginya.


30
Saya pikir poin Anda tentang column == expressionvs keyword = expressionadalah poin kunci untuk membuat perbedaan antara filterdan filter_by. Terima kasih!
Hollister

2
Saya baru mengenal sqlalchemy jadi maafkan saya jika ini adalah pertanyaan bodoh, tetapi filter_by () tampaknya tidak memungkinkan bahkan untuk kondisi yang sangat sederhana seperti "harga> = 100". Jadi, mengapa memiliki fungsi filter_by (), jika Anda hanya dapat menggunakannya untuk kondisi yang paling sederhana seperti "price = 100"?
PawelRoman

18
karena orang-orang menyukainya
zzzeek

3
Apakah ada perbedaan kinerja di antara mereka? Saya berpikir bahwa filter_bymungkin sedikit lebih cepat daripada filter.
Devi

6
Maksud dari penggunaannya filter_byadalah untuk dapat menulis menjorok nama bidang, untuk kelas itu, tidak ada pertanyaan yang diajukan - sementara fltermembutuhkan objek kolom yang sebenarnya - yang biasanya akan membutuhkan satu untuk mengetik (dan membaca) setidaknya nama kelas yang berlebihan. Jadi, jika seseorang ingin menyaring berdasarkan kesetaraan, itu lebih mudah.
jsbueno

36

filter_bymenggunakan argumen kata kunci, sedangkan filtermemungkinkan argumen penyaringan pythonic sukafilter(User.name=="john")


34

Ini adalah gula sintaks untuk penulisan kueri yang lebih cepat. Implementasinya dalam pseudocode:

def filter_by(self, **kwargs):
    return self.filter(sql.and_(**kwargs))

Untuk DAN Anda cukup menulis:

session.query(db.users).filter_by(name='Joe', surname='Dodson')

btw

session.query(db.users).filter(or_(db.users.name=='Ryan', db.users.country=='England'))

dapat ditulis sebagai

session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))

Anda juga bisa mendapatkan objek secara langsung dengan PK melalui getmetode:

Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)

Ketika menggunakan getcase, penting bahwa objek dapat dikembalikan tanpa permintaan basis data identity mapyang dapat digunakan sebagai cache (terkait dengan transaksi)


Contoh kode ini menyesatkan: Kelas dan instance tabel dasar deklaratif tidak memiliki metode filter atau kueri; mereka menggunakan sesi.
Turtles Are Cute

Saya mereproduksi users.filterdari jawaban sebelumnya. Dan mungkin itu salahku :) queryatribut adalah query_property dan gula yang cukup standar saat ini
enomad
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.