Câu trả lời:
filter_by
được sử dụng cho các truy vấn đơn giản trên các tên cột bằng cách sử dụng các kwarg thông thường, như
db.users.filter_by(name='Joe')
Điều tương tự có thể được thực hiện với filter
, không sử dụng kwargs, mà thay vào đó là sử dụng toán tử đẳng thức '==', đã bị quá tải trên đối tượng db.users.name:
db.users.filter(db.users.name=='Joe')
Bạn cũng có thể viết các truy vấn mạnh hơn bằng cách sử dụng filter
, chẳng hạn như các biểu thức như:
db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))
type(model.column_name == 'asdf')
→sqlalchemy.sql.elements.BinaryExpression
.filter
. một truy vấn như thế id=12345
, query(users).filter(id == id)
sẽ không lọc users.id
. Thay vào đó, nó sẽ đánh giá id == id
như True
và gửi lại tất cả người dùng. Bạn cần sử dụng .filter(users.id == id)
(như demo ở trên). Tôi đã phạm sai lầm này sớm hơn ngày hôm nay.
Chúng tôi thực sự đã có những thứ này được hợp nhất với nhau ban đầu, tức là có một phương thức giống như "bộ lọc" được chấp nhận *args
và **kwargs
, nơi bạn có thể chuyển một biểu thức SQL hoặc đối số từ khóa (hoặc cả hai). Tôi thực sự thấy rằng thuận tiện hơn rất nhiều, nhưng mọi người luôn bối rối vì nó, vì họ vẫn thường vượt qua sự khác biệt giữa column == expression
và keyword = expression
. Vì vậy, chúng tôi chia chúng ra.
column == expression
so với keyword = expression
là điểm quan trọng để tạo ra sự khác biệt giữa filter
và filter_by
. Cảm ơn!
filter_by
có thể nhanh hơn một chút filter
.
filter_by
là có thể viết tên trường, cho lớp đó, không có câu hỏi nào được hỏi - trong khi flter
yêu cầu đối tượng cột thực tế - thường sẽ yêu cầu một người gõ (và đọc) ít nhất một tên lớp dự phòng. Vì vậy, nếu một người muốn lọc theo đẳng thức, nó khá thuận tiện.
filter_by
sử dụng các đối số từ khóa, trong khi filter
cho phép các đối số lọc pythonic nhưfilter(User.name=="john")
Nó là một cú pháp đường để viết truy vấn nhanh hơn. Nó thực hiện trong mã giả:
def filter_by(self, **kwargs):
return self.filter(sql.and_(**kwargs))
Đối với AND bạn chỉ có thể viết:
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'))
có thể được viết như
session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))
Ngoài ra, bạn có thể lấy đối tượng trực tiếp bằng PK thông qua get
phương thức:
Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)
Khi sử dụng get
trường hợp quan trọng, đối tượng đó có thể được trả về mà không cần yêu cầu cơ sở dữ liệu từ identity map
đó có thể được sử dụng làm bộ đệm (liên kết với giao dịch)
users.filter
từ câu trả lời trước. Và có thể đó là lỗi của tôi :) query
thuộc tính là query_property và hiện tại nó là một loại đường tiêu chuẩn
db.users.name=='Ryan'
đánh giá một lần đến một hằng số và sau đó là vô nghĩa? Có vẻ như người ta sẽ cần sử dụng lambda để làm việc này.