2017-03-29 40 views
2

我試圖在Python 3.4中使用Flask,SQLAlchemy和Marshmallow建立一個REST API應用程序。使用SqlAlchemy和棉花糖對嵌套對象進行deseralizing錯誤

在我的模型中,我有一個User類,它與MailAddress類具有一對多關係。

如果我運行一個GET請求,我設法從數據庫中讀取數據,並將數據正確地作爲JSON字符串返回。

相反,如果我運行一個POST要求與我User對象的JSON序列化一些MailAddresses,我得到這個錯誤:

File "X:\test\...\site-packages\sqlalchemy\orm\collections.py", line 785, in bulk_replace 
     constants = existing_idset.intersection(values or()) 
    File "X:\test\...\site-packages\sqlalchemy\util\_collections.py", line 612, in intersection 
     result._members.update(self._working_set(members).intersection(other)) 
    TypeError: unhashable type: 'dict' 

我試着加入__hash__功能到我的模型類(如建議在sqlalchemy: TypeError: unhashable type creating instance, sqlalchemy)但這並沒有幫助。

下面是一個完整的代碼示例,說明此問題:

from flask import Flask, request 
from flask_marshmallow import Marshmallow 
from flask_sqlalchemy import SQLAlchemy 
from marshmallow import fields 
from sqlalchemy import Table, Column, Integer, String, ForeignKey 
from sqlalchemy.orm import relationship 

class Config(object): 
    SQLALCHEMY_DATABASE_URI = '<CONNECTION STRING HERE>' 
    SQLALCHEMY_TRACK_MODIFICATIONS = False 

app = Flask(__name__) 
app.config.from_object(Config) 
db = SQLAlchemy(app) 
ma = Marshmallow(app) 

# Model 
class MailAddress(db.Model): 
    __tablename__ = 'mail_addresses' 
    id = Column(Integer, primary_key=True) 
    user_id = Column(Integer, ForeignKey('users.id')) 
    mail_type = Column(String(200), nullable=False) 
    mail = Column(String(200), nullable=False) 
    def __init__(self, mail, mail_type): 
     self.mail = mail 
     self.mail_type = mail_type 

class MailAddressSchema(ma.ModelSchema): 
    class Meta: 
     model = MailAddress 

class User(db.Model): 
    __tablename__ = 'users' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(200), nullable=False) 
    mail_addresses = relationship('MailAddress', backref='user') 
    def __init__(self, name, mail_addresses): 
     self.name = name 
     self.mail_addresses = mail_addresses 
    def __hash__(self): 
     return hash(self.name) 

class UserSchema(ma.ModelSchema): 
    mail_addresses = fields.Nested(MailAddressSchema, many = True, only=('mail', 'mail_type')) 
    class Meta: 
     model = User 

# Routes 
user_schema = UserSchema() 

@app.route('/api/v0/user', methods=['GET']) 
def user_get(): 
    users = db.session.query(User).all() 
    return user_schema.jsonify(users, many = True), 200 

@app.route('/api/v0/user', methods=['POST']) 
def user_create(): 
    new_instance = user_schema.make_instance(request.json) 
    db.session.add(new_instance) 
    db.session.commit() 
    return user_schema.jsonify(new_instance), 201 

# Main 
if __name__ == '__main__': 
    app.run('localhost', 5555) 

有我丟失的東西?

回答

0

使用load代替make_instance

@app.route('/api/v0/user', methods=['POST']) 
def user_create(): 
    new_instance, errors = user_schema.load(request.json) 
    db.session.add(new_instance) 
    db.session.commit() 
    return user_schema.jsonify(new_instance), 201