数据层

数据层是资源管理器和数据交互的CRUD接口。它能以非常灵活的方式使用任何ORM或数据储存。我们甚至还能创建基于多个ORM和数据储存的数据层,以此来管理我们的对象。数据层针对对象和关系实现了CRUD接口,同时管理着分页、过滤和排序功能。

Flask-REST-JSONAPI基于知名的ORM SQLAlchemy框架已经实现了一个全功能的数据层。

注:

资源管理器默认的数据层使用的是SQLAlchemy。所以,如果我们要使用它,不必在资源管理器中明确声明。

为了配置数据层,我们必须在资源管理器中设置一些必要参数。

例:

from flask_rest_jsonapi import ResourceList
from your_project.schemas import PersonSchema
from your_project.models import Person

class PersonList(ResourceList):
    schema = PersonSchema
    data_layer = {'session': db.session,
                  'model': Person}

我们也能在资源管理中,给数据层,嵌入额外的方法。这里有两种额外的方法:

  • query(查询方法):“query”方法使用view_kwargs作为参数,并返回替代的查询结果。使用ResourceList资源管理器的GET方法时,会调用query,获取对象集合。
  • pre / post process(前置后置方法):所有CRUD和关系操作都有一对前置/后置处理方法。因此,我们能在数据层的每次操作前和后,添加额外的处理。每个前置/后置方法中,使用的具体参数可以参考基类flask_rest_jsonapi.data_layers.base.Base

例:

from sqlalchemy.orm.exc import NoResultFound
from flask_rest_jsonapi import ResourceList
from flask_rest_jsonapi.exceptions import ObjectNotFound
from your_project.models import Computer, Person

class ComputerList(ResourceList):
    def query(self, view_kwargs):
        query_ = self.session.query(Computer)
        if view_kwargs.get('id') is not None:
            try:
                self.session.query(Person).filter_by(id=view_kwargs['id']).one()
            except NoResultFound:
                raise ObjectNotFound({'parameter': 'id'}, "Person: {} not found".format(view_kwargs['id']))
            else:
                query_ = query_.join(Person).filter(Person.id == view_kwargs['id'])
        return query_

    def before_create_object(self, data, view_kwargs):
        if view_kwargs.get('id') is not None:
            person = self.session.query(Person).filter_by(id=view_kwargs['id']).one()
            data['person_id'] = person.id

    schema = ComputerSchema
    data_layer = {'session': db.session,
                  'model': Computer,
                  'methods': {'query': query,
                              'before_create_object': before_create_object}}

注:

数据层方法可以不必在资源管理器中声明。我们能在专用的模块或模型中声明它。

例:

from sqlalchemy.orm.exc import NoResultFound
from flask_rest_jsonapi import ResourceList
from flask_rest_jsonapi.exceptions import ObjectNotFound
from your_project.models import Computer, Person
from your_project.additional_methods.computer import before_create_object

class ComputerList(ResourceList):
    schema = ComputerSchema
    data_layer = {'session': db.session,
                  'model': Computer,
                  'methods': {'query': Computer.query,
                              'before_create_object': before_create_object}}

SQLAlchemy


必要参数:

  • session:数据层使用的session连接
  • model:数据层使用的ORM模型

可选参数:

  • id_field:自定义识别列,用于替代模型的主键
  • url_field:自定义路由中的参数名,用于替代默认的参数名id

默认情况下,当我们使用inlcude参数查询时,SQLAlchemy会懒加载关联的数据。如果我们想停用这个特性,我们可以将数据层的eagerload_includes设置为False。

定制数据层


之前提到过,我们也能创建使用我们自己的数据层。定制的数据层必须继承自基类flask_rest_jsonapi.data_layers.base.Base。通过这个基类,我们能看到在数据层中,所有可以定制的内容。

用例:

from flask_rest_jsonapi import ResourceList
from your_project.schemas import PersonSchema
from your_project.data_layers import MyCustomDataLayer

class PersonList(ResourceList):
    schema = PersonSchema
    data_layer = {'class': MyCustomDataLayer,
                  'param_1': value_1,
                  'param_2': value_2}

注:

在资源管理器的data_layer字典中,除了“class”的所有参数,都会作为数据层实例的属性。这样,便于数据层内部进行调用。