ความแตกต่างระหว่าง filter และ filter_by ใน SQLAlchemy


304

ใครสามารถอธิบายความแตกต่างระหว่างfilterและfilter_byฟังก์ชั่นใน SQLAlchemy ฉันควรใช้อันไหนดี?

คำตอบ:


393

filter_by ใช้สำหรับเคียวรีแบบง่ายเกี่ยวกับชื่อคอลัมน์โดยใช้ kwargs ปกติเช่น

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

สามารถทำได้เช่นเดียวกันfilterโดยไม่ใช้ kwargs แต่ใช้ตัวดำเนินการเท่าเทียมกัน '==' ซึ่งได้รับการโหลดมากเกินไปในวัตถุ db.users.name:

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

นอกจากนี้คุณยังสามารถเขียนข้อความค้นหาที่มีประสิทธิภาพยิ่งขึ้นโดยใช้filterเช่นนิพจน์ที่ชอบ:

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


22
มันทำงานอย่างไรภายใต้ประทุน? จะไม่db.users.name=='Ryan'ประเมินค่าหนึ่งครั้งเป็นค่าคงที่และจะไม่มีความหมายตั้งแต่นั้นมา? ดูเหมือนว่าเราจะต้องใช้แลมบ์ดาในการทำงาน
Hamish Grubijan

46
ผู้ประกอบการความเท่าเทียมกันมากเกินไป
Daniel Velkov

9
type(model.column_name == 'asdf')sqlalchemy.sql.elements.BinaryExpression
นิค T

11
.filterระมัดระวังในการใช้ แบบสอบถามเหมือนid=12345, จะไม่กรองquery(users).filter(id == id) users.idแต่จะประเมินid == idเป็นTrueและส่งคืนผู้ใช้ทั้งหมด คุณต้องใช้.filter(users.id == id)(ตามตัวอย่างด้านบน) ฉันทำผิดพลาดไปก่อนหน้านี้วันนี้
Nico Cernek

118

เราได้รวมสิ่งเหล่านี้เข้าด้วยกันในขั้นต้นจริง ๆ แล้วนั่นคือมีวิธีการที่เหมือน "ตัวกรอง" ซึ่งเป็นที่ยอมรับ*argsและ**kwargsคุณสามารถส่งนิพจน์ SQL หรืออาร์กิวเมนต์คำหลัก (หรือทั้งสองอย่าง) ที่จริงผมพบว่ามีจำนวนมากที่สะดวกสบายมากขึ้น แต่คนสับสนเสมอโดยมันตั้งแต่ที่พวกเขากำลังมักจะยังคงได้รับมากกว่าความแตกต่างระหว่างและcolumn == expression keyword = expressionดังนั้นเราจึงแยกพวกมันออก


30
ผมคิดว่าจุดของคุณเกี่ยวcolumn == expressionกับkeyword = expressionเป็นจุดสำคัญในการทำเกี่ยวกับความแตกต่างระหว่างและfilter filter_byขอบคุณ!
Hollister

2
ฉันใหม่กับ sqlalchemy ดังนั้นขอโทษด้วยถ้านี่เป็นคำถามที่โง่ แต่ filter_by () ดูเหมือนจะไม่อนุญาตแม้แต่กับเงื่อนไขง่ายๆเช่น "price> = 100" ดังนั้นทำไมถึงมี filter_by () ฟังก์ชั่นอยู่แล้วถ้าคุณสามารถใช้มันสำหรับสภาพที่ง่ายที่สุดเช่น "price = 100"
PawelRoman

18
เพราะคนชอบมัน
zzzeek

3
มีความแตกต่างระหว่างการแสดงหรือไม่? ผมคิดว่าอาจจะมีบิตเร็วกว่าfilter_by filter
Devi

6
จุดใช้filter_byคือการสามารถเขียน jut ชื่อฟิลด์สำหรับคลาสนั้นไม่มีคำถามที่ถาม - ในขณะที่flterต้องการวัตถุคอลัมน์จริง - ซึ่งโดยปกติจะต้องใช้หนึ่งในการพิมพ์ (และอ่าน) อย่างน้อยชื่อคลาสที่ซ้ำซ้อน ดังนั้นหากต้องการกรองด้วยความเสมอภาคจะสะดวกกว่า
jsbueno


34

มันเป็นน้ำตาลไวยากรณ์สำหรับการเขียนแบบสอบถามได้เร็วขึ้น การใช้งานใน pseudocode:

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

สำหรับและคุณสามารถเขียน:

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

สามารถเขียนเป็น

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

นอกจากนี้คุณสามารถรับวัตถุโดยตรงโดย PK ผ่านgetวิธีการ:

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

เมื่อใช้getเคสสิ่งสำคัญคือต้องสามารถส่งคืนอ็อบเจ็กต์โดยไม่มีการร้องขอฐานข้อมูลidentity mapซึ่งสามารถใช้เป็นแคช (เชื่อมโยงกับธุรกรรม)


ตัวอย่างโค้ดเหล่านี้ทำให้เข้าใจผิด: คลาสตารางฐานปฏิญญาและอินสแตนซ์ไม่มีตัวกรองหรือวิธีการสืบค้น พวกเขาใช้เซสชั่น
เต่าน่ารัก

ฉันทำซ้ำusers.filterจากคำตอบก่อนหน้า และอาจจะเป็นความผิดของฉัน :) queryแอตทริบิวต์query_propertyและค่อนข้างน้ำตาลมาตรฐานในปัจจุบัน
enomad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.