ใครสามารถอธิบายความแตกต่างระหว่างfilter
และfilter_by
ฟังก์ชั่นใน SQLAlchemy ฉันควรใช้อันไหนดี?
ใครสามารถอธิบายความแตกต่างระหว่างfilter
และfilter_by
ฟังก์ชั่นใน SQLAlchemy ฉันควรใช้อันไหนดี?
คำตอบ:
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'))
type(model.column_name == 'asdf')
→sqlalchemy.sql.elements.BinaryExpression
.filter
ระมัดระวังในการใช้ แบบสอบถามเหมือนid=12345
, จะไม่กรองquery(users).filter(id == id)
users.id
แต่จะประเมินid == id
เป็นTrue
และส่งคืนผู้ใช้ทั้งหมด คุณต้องใช้.filter(users.id == id)
(ตามตัวอย่างด้านบน) ฉันทำผิดพลาดไปก่อนหน้านี้วันนี้
เราได้รวมสิ่งเหล่านี้เข้าด้วยกันในขั้นต้นจริง ๆ แล้วนั่นคือมีวิธีการที่เหมือน "ตัวกรอง" ซึ่งเป็นที่ยอมรับ*args
และ**kwargs
คุณสามารถส่งนิพจน์ SQL หรืออาร์กิวเมนต์คำหลัก (หรือทั้งสองอย่าง) ที่จริงผมพบว่ามีจำนวนมากที่สะดวกสบายมากขึ้น แต่คนสับสนเสมอโดยมันตั้งแต่ที่พวกเขากำลังมักจะยังคงได้รับมากกว่าความแตกต่างระหว่างและcolumn == expression
keyword = expression
ดังนั้นเราจึงแยกพวกมันออก
column == expression
กับkeyword = expression
เป็นจุดสำคัญในการทำเกี่ยวกับความแตกต่างระหว่างและfilter
filter_by
ขอบคุณ!
filter_by
filter
filter_by
คือการสามารถเขียน jut ชื่อฟิลด์สำหรับคลาสนั้นไม่มีคำถามที่ถาม - ในขณะที่flter
ต้องการวัตถุคอลัมน์จริง - ซึ่งโดยปกติจะต้องใช้หนึ่งในการพิมพ์ (และอ่าน) อย่างน้อยชื่อคลาสที่ซ้ำซ้อน ดังนั้นหากต้องการกรองด้วยความเสมอภาคจะสะดวกกว่า
filter_by
ใช้อาร์กิวเมนต์คำหลักในขณะที่filter
อนุญาตให้ใช้อาร์กิวเมนต์การกรองแบบ pythonic เช่นfilter(User.name=="john")
มันเป็นน้ำตาลไวยากรณ์สำหรับการเขียนแบบสอบถามได้เร็วขึ้น การใช้งานใน 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และค่อนข้างน้ำตาลมาตรฐานในปัจจุบัน
db.users.name=='Ryan'
ประเมินค่าหนึ่งครั้งเป็นค่าคงที่และจะไม่มีความหมายตั้งแต่นั้นมา? ดูเหมือนว่าเราจะต้องใช้แลมบ์ดาในการทำงาน