Last active
July 2, 2017 07:25
-
-
Save michaelgodshall/f19a39abf0e319e6ca8ffdab8a930ebb to your computer and use it in GitHub Desktop.
A fix for SqlalchemyDataLayer for flask-rest-jsonapi that applies multiple relationships without Sqlalchemy errors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask_rest_jsonapi.data_layers.alchemy import SqlalchemyDataLayer | |
from flask_rest_jsonapi.schema import get_relationships | |
class ImprovedRelationshipsDataLayer(SqlalchemyDataLayer): | |
""" | |
Improves SqlalchemyDataLayer by setting multiple | |
relationships without Sqlalchemy errors | |
""" | |
def apply_relationships(self, data, obj): | |
"""Apply relationship provided by data to obj | |
:param dict data: data provided by the client | |
:param DeclarativeMeta obj: the sqlalchemy object to plug relationships to | |
:return boolean: True if relationship have changed else False | |
""" | |
relationships_to_apply = [] | |
relationship_fields = get_relationships(self.resource.schema) | |
for key, value in data.items(): | |
if key in relationship_fields: | |
related_model = getattr(obj.__class__, key).property.mapper.class_ | |
related_id_field = self.resource.schema._declared_fields[ | |
relationship_fields[key]].id_field | |
if isinstance(value, list): | |
related_objects = [] | |
for identifier in value: | |
related_object = self.get_related_object( | |
related_model, related_id_field, {'id': identifier} | |
) | |
related_objects.append(related_object) | |
# setattr(obj, key, related_objects) | |
relationships_to_apply.append({ | |
'field': key, | |
'value': related_objects | |
}) | |
else: | |
related_object = None | |
if value is not None: | |
related_object = self.get_related_object( | |
related_model, related_id_field, {'id': value} | |
) | |
# setattr(obj, key, related_object) | |
relationships_to_apply.append({ | |
'field': key, | |
'value': related_object | |
}) | |
# Wait to set relationships until all have been fetched from the db | |
for relationship in relationships_to_apply: | |
setattr(obj, relationship['field'], relationship['value']) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment