Sqlalchemy 将restful api端点重构为单独的链接资源
我正在重新分解API上的一些代码,我不确定如何在Flask Restful和SQLAlchemy中构造相关模型。部分解决方案在页面的中间 实际上,我试图做的是与此SQL等效的操作Sqlalchemy 将restful api端点重构为单独的链接资源,sqlalchemy,flask-restful,Sqlalchemy,Flask Restful,我正在重新分解API上的一些代码,我不确定如何在Flask Restful和SQLAlchemy中构造相关模型。部分解决方案在页面的中间 实际上,我试图做的是与此SQL等效的操作 SELECT tags.name FROM events, tags, events_tags WHERE events.id = events_tags.event_id AND tags.id = events_tags.tag_id AND events.id = 1 My routes最初有一个带
SELECT tags.name
FROM events, tags, events_tags
WHERE events.id = events_tags.event_id
AND tags.id = events_tags.tag_id
AND events.id = 1
My routes最初有一个带有嵌套标记集的事件和由api返回的JSON。add_resource(Events,“/Events/”)
的结构如下:
{
"event_id":"1",
"title":"Sample title",
"tags":[
{"name":"earthquake"},
{"name":"infrastructure"}
]
}
我想将标记分离为一个单独的端点:
这样我们就得到了两个JSON输出
api.添加资源(事件“/events/”)
api.添加资源(标记,/events//Tags')
由于我正在解决这个问题,并且意识到任何给定的标记都可能属于多个事件,因此我认为解决方案需要执行以下操作:
数据库中的事件/标记联接表
api中标记关联表的函数
ATagsListModel
(但我不确定这是否引用了tag\u association\u表
)
欢迎任何帮助
标签模型
标签序列化器
标签加载器
路线
端点
我使用1
的int:event\u id
值调用以下端点:
# Route_3
## GET (RETURNS) ALL TAGS FOR AN EVENT
api.add_resource(EventTags, '/events/<int:event_id>/tags')
模式
模型
修好了
我必须:
为不存在的每个表创建一个模型:(EventTag,Tag)
修改我的标记模式,以匹配我想从标记中隐藏的值
修改我的EventTags加载器以过滤三个表中的列
模型
模式
装载机
[
{"name":"earthquake"},
{"name":"infrastructure"}
]
class TagsListModel(db.Model):
__tablename__ = "tags"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
events = db.relationship("EventModel", secondary=tag_association_table, backref="tag")
class TagSchema(SQLAlchemyAutoSchema):
class Meta:
model = TagModel
load_instance = True
include_fk = True
id = auto_field(load_only=True)
class Tags(Resource):
# GET
def get(self, event_id):
schema = TagsListSchema()
result = db.session.query(TagsListModel).filter(TagsListModel.event_id == event_id)
return schema.dump(result, many=True), 200
# POST
def post(self, event_id):
event_id = event_id
name = request.json['name']
tag = TagsListModel(name=name)
db.session.add(tag)
db.session.commit()
data = ({'id' :tag.id,
'name': tag.name
})
#print(data)
response = jsonify(data)
response.status_code = 200 # or 400 or whatever
return response
# Route_1
## GET (RETURNS) A LIST OF EVENTS
## POST (CREATES) AN EVENT
api.add_resource(Events, '/events')
# Route_2
## GET (RETURNS) A SINGLE EVENT
# PUTS (UPDATES) A SINGLE EVENT
api.add_resource(Events, '/events/<int:event_id>')
# Route_3
## GET (RETURNS) ALL TAGS FOR AN EVENT
api.add_resource(Tags, '/events/<int:event_id>/tags')
[
{
"tag_id": 1,
"event_id": 1
},
{
"tag_id": 2,
"event_id": 1
}
]
# Route_3
## GET (RETURNS) ALL TAGS FOR AN EVENT
api.add_resource(EventTags, '/events/<int:event_id>/tags')
class EventTags(Resource):
# GET
def get(self, event_id):
schema = TagSchema()
result = db.session.query(TagModel).filter(TagModel.event_id == event_id)
return schema.dump(result, many=True), 200
# POST
def post(self, event_id):
event_id = event_id
tag_id = request.json['id']
tag = TagsListModel(id=id)
db.session.add(tag)
db.session.commit()
data = ({'id' :tag.id
})
#print(data)
response = jsonify(data)
response.status_code = 200 # or 400 or whatever
return response
class TagSchema(SQLAlchemyAutoSchema):
class Meta:
model = TagModel
load_instance = True
include_fk = True
tag_id = auto_field(load_only=False)
event_id = auto_field(load_only=False)
class TagModel(db.Model):
__tablename__ = "events_tags"
tag_id = Column(Integer, primary_key=True)
event_id = Column(Integer, primary_key=True)
class TagModel(db.Model):
__tablename__ = "tags"
id = Column(Integer, primary_key=True)
name = Column(db.String, nullable=False)
class EventTagModel(db.Model):
__tablename__ = "events_tags"
tag_id = Column(Integer, primary_key=True)
event_id = Column(Integer, primary_key=True)
class TagSchema(SQLAlchemyAutoSchema):
class Meta:
model = TagModel
load_instance = True
include_fk = True
id = auto_field(load_only=True) # Only one field removed so this remained pretty identical.
result = db.session.query(TagModel)
.filter(TagModel.id == EventTagModel.tag_id)
.filter(EventModel.id == EventTagModel.event_id)
.filter(EventTagModel.event_id == event_id)
# result = db.session.query(TagModel). # REMOVED
# filter(TagModel.event_id == event_id). # REMOVED