from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from contextlib import contextmanager
classSQLAlchemy(_SQLAlchemy):@contextmanagerdefauto_commit(self):try:
yield
self.session.commit()
except Exception as e:
self.session.rollback()
raise e
db = SQLAlchemy()
###### 例如 #######from app.libs.user import User
with db.auto_commit():
user = User()
user.email = 'xxx'
user.nickname = 'xxx'
user.password = 'xxx'
db.session.add(user)
from flask_sqlalchemy import BaseQuery as _BaseQuery
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from contextlib import contextmanager
classSQLAlchemy(_SQLAlchemy):@contextmanagerdefauto_commit(self):try:
yield
self.session.commit()
except Exception as e:
self.session.rollback()
raise e
classBaseQuery(_BaseQuery):deffilter_by(self, **kwargs):if'status'notin kwargs: #如果status字段不在fliter_by中,默认添加status=1
kwargs['status'] = 1return super(BaseQuery, self).filter_by(**kwargs) #返回父类的fliter_by的执行
db = SQLAlchemy(query_class=BaseQuery) # 在SQLAlchemy中注册一下### 查询 ###
user_List = User.query.filter_by(xxx=xxx,xxx=xxx) # 默认status=1, 方便查询被逻辑删除的数据
3.自定制BaseQuery下的first_or_404
BaseQuery源码
classBaseQuery(orm.Query):"""SQLAlchemy :class:`~sqlalchemy.orm.query.Query` subclass with convenience methods for querying in a web application.
This is the default :attr:`~Model.query` object used for models, and exposed as :attr:`~SQLAlchemy.Query`.
Override the query class for an individual model by subclassing this and setting :attr:`~Model.query_class`.
"""
...
...
deffirst_or_404(self):"""Like :meth:`first` but aborts with 404 if not found instead of returning ``None``."""
rv = self.first()
if rv isNone:
abort(404)
return rv
由此可见它出错会抛出404的(HTML)异常,我们重写它抛出json的异常结果
class BaseQuery(_BaseQuery):
......
def first_or_404(self): # 重写
rv = self.first()
if rv is None:
raise My_not_found() # 此处改写return rv
### 查询后就不必判断对象是否为空
user = User.query.filter_by(xxx=xxx,xxx=xxx).first_or_404()