Skip to content

Instantly share code, notes, and snippets.

@danielmt
Forked from mattupstate/example.py
Last active July 1, 2021 11:41
Show Gist options
  • Save danielmt/98a303633d6ade7e0bba1b94af12f872 to your computer and use it in GitHub Desktop.
Save danielmt/98a303633d6ade7e0bba1b94af12f872 to your computer and use it in GitHub Desktop.
JSON Patch SQLAlchemy models w/ Flask
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)
Flask-SQLAlchemy
dictalchemy
jsonpatch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment