Bạn có thể phân lớp cơ sở Query
lớp để thêm các phương pháp của riêng bạn:
from sqlalchemy.orm import Query
class MyQuery(Query):
def all_active(self):
return self.filter(User.is_active == True)
Sau đó bạn nói với SQLAlchemy sử dụng lớp truy vấn mới này khi bạn tạo phiên (docs here). Từ mã của bạn có vẻ như bạn có thể sử dụng Flask-SQLAlchemy, vì vậy bạn sẽ làm điều đó như sau:
db = SQLAlchemy(session_options={'query_cls': MyQuery})
Nếu không, bạn sẽ vượt qua đối số trực tiếp đến sessionmaker
:
sessionmaker(bind=engine, query_cls=MyQuery)
Tính đến ngay bây giờ, đối tượng truy vấn mới này không thú vị bởi vì chúng tôi đã mã hóa cứng lớp User
trong phương thức, vì vậy nó sẽ không hoạt động cho bất kỳ thứ gì khác. Triển khai tốt hơn sẽ sử dụng lớp cơ bản của truy vấn để xác định bộ lọc nào cần áp dụng. Điều này hơi phức tạp nhưng cũng có thể được thực hiện:
class MyOtherQuery(Query):
def _get_models(self):
"""Returns the query's underlying model classes."""
if hasattr(query, 'attr'):
# we are dealing with a subquery
return [query.attr.target_mapper]
else:
return [
d['expr'].class_
for d in query.column_descriptions
if isinstance(d['expr'], Mapper)
]
def all_active(self):
model_class = self._get_models()[0]
return self.filter(model_class.is_active == True)
Cuối cùng, lớp truy vấn mới này sẽ không được sử dụng bởi các mối quan hệ động (nếu bạn có). Để cho những người cũng sử dụng nó, bạn có thể vượt qua nó như là đối số khi bạn tạo các mối quan hệ:
users = relationship(..., query_class=MyOtherQuery)
Tôi tự hỏi nếu bất cứ điều gì trong khác [câu hỏi/trả lời] này (http://stackoverflow.com/questions/7604967/ sqlalchemy-build-query-filter-động-từ-dict) có thể được sử dụng cho việc này? (Tuy nhiên, ít phương thức tùy chỉnh hơn ... và nhiều bộ lọc động tùy chỉnh hơn.) – summea