Modifier

Exemple,

class A(ComplexModel):
    Id = Unicode

class B(ComplexModel):
    __extends__ = A
    Name = Unicode

@rpc(String, _returns=A)
def hello(self, name):
    ret = B()
    B.Id = '123'
    B.Name = name
    return ret

Comment gérez-vous ce comportement pour qu'il ne renvoie pas un objet de A?


Comment écrire les décorateurs spyne pour renvoyer correctement plusieurs types? Si, par exemple, _returns est défini sur ZObj, alors renvoyer un XAccount (comme dans le code) ne fait rien.

Puis-je écrire l'objet XAccount pour qu'il étende ZObj et soit un type de retour valide?

@rpc(String, _returns=(ZObj, XAccount))
def hello(self, name):
    acc = XAccount(
        user_name = name.upper(),
        first_name = name,
        last_name = 'last ' + name
    )
    return acc

Exemples de classe ...

class ZObj(ComplexModel):
    id = Unicode(pattern='[a-zA-Z0-9]{32}|\d+')

class Account(DeclarativeBase):
    __tablename__ = 'account'

    id = Column(Integer, primary_key=True)
    user_name = Column(String(256))
    first_name = Column(String(256))
    last_name = Column(String(256))


class XAccount(TableModel):
    __table__ = Account.__table__
0
blakev 14 juil. 2015 à 00:19

2 réponses

Meilleure réponse

Suppression de ma réponse précédente car vous avez apparemment besoin de polymorphisme, pas de types de retour multiples.

Donc, il y a deux façons de faire du polymorphisme dans Spyne: la méthode Python et la méthode Spyne.

Laisser:

class A(ComplexModel):
    i = Integer

class B(A):
    s = Unicode

class C(A):
    d = DateTime

La méthode Python utilise le typage canard pour renvoyer des valeurs.

Définissons une classe générique:

class GenericA(ComplexModel):
    i = Integer
    s = Unicode
    d = DateTime

Et utilisez-le comme valeur de retour de notre exemple de service:

class SomeService(ServiceBase):
    @rpc(Unicode(values=['A', 'B', 'C']), _returns=GenericA)
    def get_some_a(self, type_name):
        # (...)

De cette façon, vous obtenez vos données, mais elles sont marquées comme un objet GenericA. Si vous ne vous souciez pas de cela, vous pouvez créer une classe qui a tous les types de tous les objets (en supposant que les attributs avec les mêmes noms ont le même type) et en finir avec. C'est facile, stable et fonctionne aujourd'hui.

Si cela ne suffit pas à vos besoins, vous devez faire le polymorphisme à la manière de Spyne. Pour ce faire, définissez d'abord votre type de retour sur la classe de base:

class SomeService(ServiceBase):
    @rpc(Unicode(values=['A', 'B', 'C']), _returns=A)
    def get_some_a(self, type_name):
        # (...)

Et marquez votre protocole de sortie comme polymorphe:

application = Application([SomeService], 'tns',
    in_protocol=Soap11(validator='lxml'),
    out_protocol=Soap11(polymorphic=True)
)

Cela nécessite au moins Spyne-2.12.

Exemple de travail: https://github.com/arskom/spyne/ blob / a1b3593f3754a9c8a6787c29ff50f591db89fd49 / examples / xml / polymorphism.py

1
Burak Arslan 16 juil. 2015 à 10:54

De plus, vous n'avez pas besoin de faire ceci:

class Account(DeclarativeBase):
    __tablename__ = 'account'

    id = Column(Integer, primary_key=True)
    user_name = Column(String(256))
    first_name = Column(String(256))
    last_name = Column(String(256))

class XAccount(TableModel):
    __table__ = Account.__table__

Cela fonctionne aussi bien:

from spyne import TTableModel

TableModel = TTableModel() # Think of this as Spyne's declarative_base

class Account(TableModel):
    __tablename__ = 'account'

    id = Integer(primary_key=True)
    user_name = Unicode(256)
    first_name = Unicode(256)
    last_name = Unicode(256)

Où se trouvent les métadonnées de votre table TableModel.Attributes.sqla_metadata

Les objets créés de cette manière sont utilisables à la fois dans les requêtes SQLAlchemy et en tant que types Spyne.

0
Burak Arslan 16 juil. 2015 à 11:01