在路由端点之外使用请求数据

Using request data outside of routing endpoint

我正在使用 Flask API。在我的一个路由端点中,我想使用带有 flask.request 对象的 remote_user 属性的模型实例作为默认值。

我的模型的 class 定义是:

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)

问题是我需要在端点之外定义这个 class,但是当我在端点之外使用请求对象时,我得到错误:RuntimeError: working outside of request context.

作为测试,我尝试在端点中定义 class,它在我第一次到达端点并实例化模型时起作用,但是当我之后到达端点时出现错误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.

我需要在另一个端点中使用此模型 class,那么如何在我的端点中使用请求上下文之外的请求对象定义我的模型 class?

flask.request is a proxy that is valid only during a request. The models are added to MetaData on startup,因此它会在收到请求之前尝试解析默认值 request.remote_address

当您将模型声明移动到 api 层时,模型会在每次请求时实例化,这会引发错误,因为 MetaData 只接受唯一的 table 名称。

SQLAlchemy 允许您定义一个函数作为字段的默认值。这里的区别在于可调用对象仅在插入或更新时执行。因此,如果您将字段定义为:

user = Column(String(48), default=lambda: request.remote_user)

request 只有在您与数​​据库交互时才会得到解析。需要注意的是,当您不在请求上下文中时,您将无法使用此模型 class。