Data layer¶
Note
The default data layer used by a resource manager is the SQLAlchemy one. So if you want to use it, you don’t have to specify the class of the data layer in the resource manager
To configure the data layer you have to set its required parameters in the resource manager.
Example:
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}
You can also plug additional methods to your data layer in the resource manager. There are two kinds of additional methods:
- query: the “query” additional method takes view_kwargs as parameter and return an alternative query to retrieve the collection of objects in the GET method of the ResourceList manager.
- pre / post process methods: all CRUD and relationship(s) operations have a pre / post process methods. Thanks to it you can make additional work before and after each operations of the data layer. Parameters of each pre / post process methods are available in the flask_rest_jsonapi.data_layers.base.Base base class.
Example:
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}}
Note
You don’t have to declare additional data layer methods in the resource manager. You can declare them in a dedicated module or in the declaration of the model.
Example:
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¶
Required parameters:
session: the session used by the data layer model: the model used by the data layer
Optional parameters:
id_field: the field used as identifier field instead of the primary key of the model url_field: the name of the parameter in the route to get value to filter with. Instead “id” is used.
By default SQLAlchemy eagerload related data specified in include querystring parameter. If you want to disable this feature you must add eagerload_includes: False to data layer parameters.
Custom data layer¶
Like I said previously you can create and use your own data layer. A custom data layer must inherit from flask_rest_jsonapi.data_layers.base.Base. You can see the full scope of possibilities of a data layer in this base class.
Usage example:
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}
Note
All items except “class” in the data_layer dict of the resource manager will be plugged as instance attributes of the data layer. It is easier to use in the data layer.