2

我正在尝试使用 Flask、SQLAlchemy 和 Marshmallow 在 Python 3.4 中构建一个 REST API 应用程序。

在我的模型中,我有一个User类与一个类具有一对多关系MailAddress

如果我运行一个GET请求,我会设法从数据库中读取数据,并且数据会以 JSON 字符串的形式正确返回。

相反,如果我使用 some 对我的对象进行POSTJSON 序列化来运行请求,我会收到以下错误:UserMailAddresses

    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)

有什么我想念的吗?

4

1 回答 1

1

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
于 2017-05-22T20:23:54.187 回答