我正在使用Flask作为API。在我的一个路由端点中,我想使用带有flask.request对象的remote_user属性的模型实例作为默认值。
我的模型的类定义是:
class Results(db.Model):
__tablename__ = 'results'
id = Column(Integer, primary_key=True, autoincrement=True)
sid = Column(Integer)
attribute = Column(String(2048))
value_s = Column(String(2048))
value_d = Column(Float)
user = Column(String(48), default=request.remote_user)
问题是我需要在端点之外定义这个类,但是当我在端点之外使用请求对象时,我得到错误:RuntimeError: working outside of request context.
作为测试,我尝试在端点中定义类,并且它第一次触及端点并实例化模型时工作,但是当我在此之后命中端点时,我收到sqlalchemy.exc.InvalidRequestError: Table '[tablename]' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
的错误
我需要在另一个端点使用此模型类,那么如何使用端点中请求上下文之外的请求对象来定义模型类?
答案 0 :(得分:1)
flask.request是仅在请求期间有效的代理。模型已添加到MetaData
on startup,因此它会在收到请求之前尝试解析默认值request.remote_address
。
当您将模型声明移动到api层时,模型会在每个请求上实例化,这会引发错误,因为MetaData
只接受唯一的表名。
SQLAlchemy允许您将函数定义为字段的默认值。这里的区别在于可调用仅在插入或更新时执行。因此,如果您将字段定义为:
user = Column(String(48), default=lambda: request.remote_user)
仅当您与数据库交互时才会解析 request
。需要注意的是,当您不在请求上下文中时,您将无法使用此模型类。