Domanda

Ho una domanda riguardante l'estensione riposante del pallone.Sono appena iniziato a usarlo e affrontato un problema.Ho entità flask-sqlalchemy che sono collegate a una relazione di molti-to-one e voglio che quel riposante endpoint ritornano l'entità genitore con tutti i suoi figli in json usando Marshaller.Nel mio set di custodia contiene molti parametri.Guardai il fiasco-riposante Docs Ma non c'era alcuna spiegazione comePer risolvere questo caso.

Sembra che mi manchi qualcosa di ovvio ma non riesce a capire alcuna soluzione. Ecco il mio codice:

# entities
class Set(db.Model):
    id = db.Column("id", db.Integer, db.Sequence("set_id_seq"), primary_key=True)
    title = db.Column("title", db.String(256))

    parameters = db.relationship("Parameters", backref="set", cascade="all")


class Parameters(db.Model):
    id = db.Column("id", db.Integer, db.Sequence("parameter_id_seq"), primary_key=True)
    flag = db.Column("flag", db.String(256))
    value = db.Column("value", db.String(256))
    set_id = db.Column("set_id", db.Integer, db.ForeignKey("set.id"))


# marshallers

from flask.ext.restful import fields

parameter_marshaller = {
    "flag": fields.String,
    "value": fields.String
}

set_marshaller = {
    'id': fields.String,
    'title': fields.String,
    'parameters': fields.List(fields.Nested(parameter_marshaller))
}

# endpoint    

class SetApi(Resource):

    @marshal_with(marshallers.set_marshaller)
    def get(self, set_id):
        entity = Set.query.get(set_id)
        return entity


restful_api = Api(app)
restful_api.add_resource(SetApi, "/api/set/<int:set_id>")
.

Ora quando chiamo /api/set/1 ottengo Errore del server:

TypeError: 'Set' object is unsubscriptable

Quindi ho bisogno di un modo per definire correttamente set_marshaller che endpoint restituisce questo json:

{
  "id": : "1",
  "title": "any-title",
  "parameters": [
       {"flag": "any-flag", "value": "any-value" },
       {"flag": "any-flag", "value": "any-value" },
       .....
   ]
}
.

Apprezzo qualsiasi aiuto.

È stato utile?

Soluzione

Ho trovato la soluzione a quel problema da solo.

Dopo aver giocato con flask-restful Scopri che ho fatto alcuni errori:

Primo set_marshaller dovrebbe assomigliare a questo:

blob_marshaller = {
    'id': fields.String,
    'title': fields.String,
    'parameters': fields.Nested(parameter_marshaller)
}
.

Marshaller senza riposo può gestire il caso se il parametro è Elenco e Marshals all'elenco json.

Un altro problema è stato che nei parametri impostati API ha il caricamento pigro, quindi quando provo a Marshall Set ho ottenuto KeyError: 'parameters', quindi ho bisogno di caricare esplicitamente parametri come questo:

class SetApi(Resource):

     @marshal_with(marshallers.set_marshaller)
     def get(self, set_id):
        entity = Set.query.get(set_id)
        entity.parameters # loads parameters from db
        return entity
.

o un'altra opzione è quella di modificare la relazione del modello:

parameters = db.relationship("Parameters", backref="set", cascade="all" lazy="joined")
.

Altri suggerimenti

Questa è un'aggiunta a Zygimantas Risposta :

Sto usando il pallone-riposante e questa è una soluzione al caricamento delle proprietà annidate.

È possibile passare un relato per il decoratore del maresciallo:

class OrgsController(Resource):
    @marshal_with(Organization.__json__())
    def get(self):
        return g.user.member.orgs
.

Quindi aggiornare i modelli per restituire i campi delle risorse per la propria entità. Le entità nidificate restituiranno quindi i campi delle risorse per la sua entità relativamente.

class Organization(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    ...

    @staticmethod
    def __json__(group=None):
        _json = {
            'id': fields.String,
            'login': fields.String,
            'description': fields.String,
            'avatar_url': fields.String,
            'paid': fields.Boolean,
        }

        if group == 'flat':
            return _json

        from app.models import Repository
        _json['repos'] = fields.Nested(Repository.__json__('flat'))

        return _json

class Repository(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('organization.id'))
    owner = db.relationship('Organization', lazy='select', backref=db.backref('repos', lazy='select'), foreign_keys=[owner_id])
    ...

    @staticmethod
    def __json__(group=None):
        _json = {
            'id': fields.String,
            'name': fields.String,
            'updated_at': fields.DateTime(dt_format='iso8601'),
        }

        if group == 'flat':
            return _json

        from app.models import Organization
        _json['owner'] = fields.Nested(Organization.__json__('flat'))

        return _json
.

Questo dà la rappresentazione sto cercando e onorando il caricamento pigro:

[
    {
        "avatar_url": "https://avatars.githubusercontent.com/u/18945?v=3",
        "description": "lorem ipsum.",
        "id": "1805",
        "login": "foobar",
        "paid": false,
        "repos":
            [
                {
                    "id": "9813",
                    "name": "barbaz",
                    "updated_at": "2014-01-23T13:51:30"
                },
                {
                    "id": "12860",
                    "name": "bazbar",
                    "updated_at": "2015-04-17T11:06:36"
                }
            ]
    }
]
.

Mi piace

1) Come questo approccio mi consente di definire i miei campi di risorse per entità ed è disponibile per tutti i miei percorsi di risorse attraverso l'app.

2) Come l'argomento del gruppo mi consente di personalizzare la rappresentazione comunque che desidero. Ho solo 'piatto' qui, ma qualsiasi logica può essere scritta e trasmessa a oggetti nidificati più profondi.

3) Le entità vengono caricate solo se necessario.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top