我对 Flask-Marshmallow / Flask-SQLAlchemy 非常陌生,我正在尝试使用烧瓶和 mysql 设置我自己的 REST API。
这是我要发布的有效负载。我希望能够只发送 ID 并排除所有其他字段:
{
"code": "FG034",
"product_name": "test test2",
"description": "Description",
"init_date": "2021-01-10",
"init_by": {
"id": "27bb9e1acad247618fb2c3e016ae841c"
}
}
这是我发送该有效负载时遇到的错误:
ERROR in utils: (pymysql.err.IntegrityError) (1048, "Column 'full_name' cannot be null")
[SQL: INSERT INTO user (id, full_name, initials, hashed_password, is_active) VALUES (%(id)s, %(full_name)s, %(initials)s, %(hashed_password)s, %(is_active)s)]
[parameters: {'id': '27bb9e1acad247618fb2c3e016ae841c', 'full_name': None, 'initials': None, 'hashed_password': None, 'is_active': 1}]
(Background on this error at: http://sqlalche.me/e/13/gkpj)
这很奇怪,因为我不想在用户表中插入任何东西......
当我将所有字段放入其中时,会按预期添加:
{
"code": "FG034",
"product_name": "test test2",
"description": "Description",
"init_date": "2021-01-10",
"init_by": {
"id": "27bb9e1acad247618fb2c3e016ae841c",
"initials": "EE",
"email": "example@gmail.com",
"full_name": "Example Exampleton",
"is_active": true
}
}
这是添加 FinishedGood 的结果的 GET(这是我想要的):
{
"code": "FG034",
"init_date": "2021-01-10",
"description": "Description",
"id": 3,
"is_active": true,
"init_by": {
"email": "example@gmail.com",
"id": "27bb9e1acad247618fb2c3e016ae841c",
"is_active": true,
"full_name": "Example Exampleton",
"initials": "EE"
},
"product_name": "test test2"
}
也许我完全错误地使用了这个,但谁能告诉我:
- 为什么它试图插入用户表?我想要的只是要加载到 init_by_id 中的主键
- 有没有办法像我在开始时显示的那样仅使用 ID 发布有效负载?
这是我的类和模式:
class User(db.Model):
id = db.Column(db.CHAR(32), primary_key=True, default=uuid.uuid4().hex)
email = db.Column(db.String(255), primary_key=True)
full_name = db.Column(db.String(255), nullable=False)
initials = db.Column(db.String(3), unique=True, nullable=False)
hashed_password = db.Column(db.Text, nullable=False)
is_active = db.Column(db.Boolean, default=True)
class UserSchema(ma.SQLAlchemySchema):
class Meta:
model = User
load_instance = True
sqla_session = db.session
id = ma.auto_field()
email = ma.auto_field(required=False)
full_name = ma.auto_field(required=False)
initials = ma.auto_field(required=False)
is_active = ma.auto_field(required=False)
class FinishedGood(db.Model):
id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.String(255), unique=True, nullable=False)
product_name = db.Column(db.String(255), nullable=False)
description = db.Column(db.Text)
init_date = db.Column(db.Date, nullable=False)
init_by_id = db.Column(db.CHAR(32), db.ForeignKey(User.id), nullable=False)
init_by = db.relationship(User)
is_active = db.Column(db.Boolean, default=True)
class FinishedGoodSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = FinishedGood
load_instance = True
sqla_session = db.session
init_by = ma.Nested(UserSchema)
最后是我的发布方法:
def post_finished_good():
data = request.get_json(force=True)
fg = FinishedGoodSchema().load(data)
db.session.add(fg)
db.session.commit()
return FinishedGoodSchema().jsonify(fg), 201