Ich habe eine Flask-RESTful-basierte API, die derzeit zwei Blueprints hat, so dass ich die API mit rückwärtskompatiblen Änderungen versionieren kann.Verschiedene Modell resource_fields für verschiedene Blueprints
from api_1_0 import api_bp as api_1_0_blueprint
app.register_blueprint(api_1_0_blueprint, url_prefix='/api/v1.0')
from api_1_1 import api_bp as api_1_1_blueprint
app.register_blueprint(api_1_1_blueprint, url_prefix='/api/v1.1')
Immer wenn ich eine rückwärtskompatible Änderung vornehmen muss (z. B. Entfernen eines Endpunkts), erstelle ich einen neuen Blueprint. Derzeit teilen sich die Blueprints die gleiche models.py
Datei und definieren die Datenbanktabellen und die JSON-Darstellung jedes Modells.
Ich muss jetzt eine neue Version der API erstellen, in der ein bestimmtes Ressourcenfeld email
von einem string
Datentyp in array[string]
geändert wird. Die vorhandenen Versionen der API müssen die ursprüngliche Ressourcendarstellung beibehalten.
ich versucht habe, in jedem Plan Ordner eine models.py
Datei platzieren, so dass der neuere Entwurf v1.2
hat es selbst ist resource_fields
Definition, aber dadurch ich mit diesem Fehler am Ende:
sqlalchemy.exc.InvalidRequestError: Table '' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
Ich verstehe, das ist passiert, weil ich im Grunde die gleichen Datenbanktabellen für jeden Bauplan definiere. Wirklich alles, was ich will, ist die resource_fields
per Blueprint zu ändern, da das Datenbankschema über alle API-Versionen immer gleich sein wird, ist es nur die JSON-Antwort, die sich ändern kann. (Ich werde die @property
Dekorateur verwenden, um die neuen Felder zu erstellen)
Angesichts dieser Einrichtung, wie kann ich die resource_fields
per Blueprint ändern?
Unten finden Sie einen Beispielcode (vereinfacht) aus meinem Projekt.
app/models.py - https://gist.github.com/MattHealy/4c9d2c03615e3381774235bbbc398437
from app import db
from flask.ext.restful import fields
@swagger.model
class Contact(db.Model):
resource_fields = {
'email': fields.String
}
email = db.Column(db.String(100))
app/api_1_1/resources/contacts.py - https://gist.github.com/MattHealy/556c93fe33a929e469ae18bf76db83b1
from flask.ext.restful import Resource, marshal, reqparse
from ... models import Contact
class ContactAPI(Resource):
"Retrieve details of a single contact"
@swagger.operation(
nickname = "contact",
responseClass=Contact.__name__,
parameters=[
{
"name": "id",
"description": "ID of the contact",
"required": True,
"allowMultiple": False,
"dataType": "int",
"paramType": "path"
},
],
responseMessages=[
{
"code": 200,
"message": "Contact retrieved"
},
],
summary="Get details of a single contact",
)
def get(self, id):
contact = Contact.query.get(id)
return { 'contact': marshal(contact, Contact.resource_fields) }