Flask 开发API接口时,使用flask-restfull 具有简洁的接口,通过将SQLAlchemy和marshmallow集成在Flask,可以方便得对数据库增删查改。
问题一:flask-marshmallow-sqlalchemy集成
在项目中使用了flask-marshmallow和marshmallow-sqlalchemy插件,需要简单的配置才能使用
from flask import Flask
from flask_marshmallow import Marshmallow
# 这里注意先后顺序
app = Flask(__name__)
ma = Marshmallow(app)
或者
ma = Marshmallow()
db.init_app(app)
ma.init_app(app)
问题二:定义ModelSchema
ModelSchema是marshmallow-sqlalchemy提供的子类,可以自动根据表的定义生成field,类似于djangorestframework中的Serializer,通过ma.Nested定义主从结构,可以自动完成JSON中复杂结构的主从表保存和序列化。
class DocAnnotationSchema(ma.ModelSchema):
class Meta:
fields = ["id", "start_offset","end_offset","text_span","replacement",'label',"priority","ndocs"]
model = ClaimAnnotation
sqla_session = db.session
class ClaimDocChildSchema(ma.ModelSchema):
annotations = ma.Nested(DocAnnotationSchema, many=True)
class Meta:
fields = ["id","category_id","name","text","annotations"]
model = ClaimDoc
sqla_session = db.session
问题三:主从表级联删除
当需要通过一个API删除主从表,需要在sqlalchemy 中model中定义cascade 属性
选项1(首选)
其次,SqlAlchemy支持两种不同的级联。 第一个,也是我建议的那个,内置在您的数据库中,通常采用外键声明约束的形式。 在PostgreSQL中它看起来像这样:
CONSTRAINT child_parent_id_fkey FOREIGN KEY (parent_id)
REFERENCES parent_table(id) MATCH SIMPLE
ON DELETE CASCADE
这意味着当您从parent_table删除记录时, parent_table您删除parent_table所有相应行。 它快速可靠,可能是您最好的选择。 你可以通过ForeignKey在SqlAlchemy中设置它(这是子表定义的一部分):
parent_id = db.Column(db.Integer, db.ForeignKey('parent.id', ondelete='CASCADE'))
parent = db.relationship('Parent', backref=backref('children', passive_deletes=True))
ondelete='CASCADE'是在表上创建ON DELETE CASCADE的部分。
使用passive_deletes=True指定relationship ? 如果你没有,整个事情都行不通。 这是因为默认情况下,当您删除父记录时,SqlAlchemy会做一些非常奇怪的事情。 它将所有子行的外键设置为NULL 。 因此,如果从parent_table中删除id = 5的行,那么它将基本执行
UPDATE child_table SET parent_id = NULL WHERE parent_id = 5
选项2
另一种方法是让SqlAlchemy为你做。 这是使用relationship的cascade参数设置的。 如果您在父表上定义了关系,它看起来像这样:
children = relationship('Child', cascade='all,delete', backref='parent')
如果关系在孩子身上,你可以这样做:
parent = relationship('Parent', backref=backref('children', cascade='all,delete'))
同样,这是孩子所以你必须调用一个名为backref的方法并将级联数据放在那里。
Comments