-
-
Save danielmt/98a303633d6ade7e0bba1b94af12f872 to your computer and use it in GitHub Desktop.
JSON Patch SQLAlchemy models w/ Flask
This file contains 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 dictalchemy import make_class_dictable | |
from flask import Flask, request, jsonify, json | |
from flask_sqlalchemy import SQLAlchemy | |
from jsonpatch import JsonPatch, JsonPatchException | |
app = Flask(__name__) | |
app.debug = True | |
db = SQLAlchemy(app) | |
make_class_dictable(db.Model) | |
@app.errorhandler(JsonPatchException) | |
def on_patch_exception(error): | |
return jsonify({'message': 'Invalid JSON patch'}), 400 | |
class Book(db.Model): | |
id = db.Column(db.Integer, primary_key=True) | |
title = db.Column(db.String(20)) | |
description = db.Column(db.Text) | |
def patch(instance, **kwargs): | |
# Create the patch object | |
patch = JsonPatch(request.get_json()) | |
# Get a dictionary instance of the model instance | |
data = instance.asdict(exclude_pk=True, **kwargs) | |
# Apply the patch to the dictionary instance of the model | |
data = patch.apply(data) | |
# Apply the patched dictionary back to the model | |
instance.fromdict(data) | |
@app.route('/books/<resource_id>', methods=['PATCH']) | |
def books(resource_id): | |
book = Book.query.get_or_404(resource_id) | |
patch(book) | |
db.session.commit() | |
return jsonify(book.asdict()) | |
with app.app_context(): | |
db.create_all() | |
db.session.add(Book(title='Title', description='Description')) | |
db.session.commit() | |
client = app.test_client() | |
data = json.dumps([ | |
{'op': 'replace', 'path': '/title', 'value': 'New Title'}, | |
{'op': 'replace', 'path': '/description', 'value': 'New Description'} | |
]) | |
response = client.patch('/books/1', content_type='application/json', data=data) | |
assert response.status_code == 200 | |
print(response.data) | |
print('-' * 40) | |
data = json.dumps({'bogus': 'value'}) | |
response = client.patch('/books/1', content_type='application/json', data=data) | |
assert response.status_code == 400 | |
print(response.data) |
This file contains 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
Flask-SQLAlchemy | |
dictalchemy | |
jsonpatch |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment