在我的模型中,flask-restless 不适用于混合属性

Posted

技术标签:

【中文标题】在我的模型中,flask-restless 不适用于混合属性【英文标题】:flask-restless dont work with hybrid property in my models 【发布时间】:2018-06-18 10:22:27 【问题描述】:

我正在为我们的前端开发人员创建 api,但我的模型中的对象有问题。我使用 flask-sqlalchemypython2.7

manager = flask_restless.APIManager(app, session = s)
manager.create_api(Basic_Abones)

ORM 模型

class Basic_Abones(Base):
    __tablename__ = 'basic_abones'
    id = Column(Integer, primary_key=True)
    name = Column(String(120))
    part = Column(Integer)
    current_price = Column(Integer)
    complex_a = relationship("Complex_Abon", secondary=assoc, back_populates='basic')
    discount = Column(Integer)


    def __repr__(self):
        return self.name

    @hybrid_property
    def price_with_discount(self):
        try:
            return self.current_price * self.discount / 100

        except TypeError:
            return 0 

例外

127.0.0.1 - - [09/Jan/2018 13:10:04] "GET / HTTP/1.1" 200 -
--------------------------------------------------------------------------------
ERROR in views [/home/yozh/AllStars/allstars/local/lib/python2.7/site-packages/flask_restless/views.py:1178]:
Neither 'hybrid_property' object nor 'ExprComparator' object associated with Basic_Abones.price_with_discount has an attribute 'property'
--------------------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/yozh/AllStars/allstars/local/lib/python2.7/site-packages/flask_restless/views.py", line 1172, in _search
    result = search(self.session, self.model, search_params)
  File "/home/yozh/AllStars/allstars/local/lib/python2.7/site-packages/flask_restless/search.py", line 587, in search
    query = create_query(session, model, search_params, _ignore_order_by)
  File "/home/yozh/AllStars/allstars/local/lib/python2.7/site-packages/flask_restless/search.py", line 549, in create_query
    _ignore_order_by)
  File "/home/yozh/AllStars/allstars/local/lib/python2.7/site-packages/flask_restless/search.py", line 505, in create_query
    pks = primary_key_names(model)
  File "/home/yozh/AllStars/allstars/local/lib/python2.7/site-packages/flask_restless/helpers.py", line 216, in primary_key_names
    and isinstance(field.property, ColumnProperty)
  File "/home/yozh/AllStars/allstars/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 314, in __getattr__
    attribute)
AttributeError: Neither 'hybrid_property' object nor 'ExprComparator' object associated with Basic_Abones.price_with_discount has an attribute 'property'
127.0.0.1 - - [09/Jan/2018 13:10:14] "GET /api/basic_abones HTTP/1.1" 400 -

我不知道会发生什么,我无法在 google 中找到已解决的问题。 谢谢你,对不起我的英语

PS:这个烧瓶插件工作正常,模型中没有混合属性,但混合列对我的项目很重要

【问题讨论】:

您使用的是什么版本的 Flask-Restless?至少,您的回溯中的文件 helpers.py 与 Github 中的文件不匹配。 Github 中的版本在primary_key_names() 中做了正确的事情(tm)并使用mapper.primary_key 而不是直接检查属性。 我使用的是 Flask-Restless 的 0.17.0 版本,因为最后一个版本是 Beta(1.0.0b1)。作者推荐使用稳定版本,即0.17.0 谢谢,我会阅读更多文档。 【参考方案1】:

看起来,这是Flask-Restless 项目中的一个已知错误,而不是flask-sqlalchemy。

它已经在 master 分支上修复,但当前没有实现该解决方案的稳定版本。

问题的根本原因在 flask-restless 的 helpers.py 文件中,在“primary_key_names”中,它试图访问 hybrid_property 对象的一个​​名为 property 的字段。由于它不存在,因此引发异常。

可能的解决方案:

    设置对 Flask-Restless 的 master 分支的依赖。这个解决方案不是很好的 IMO,因为它有点临时(未来的更改可能会破坏您的代码)。 fork 存储库并实施原始 github issue 中提出的解决方案。

    我选择实现的解决方案是解决我的代码中的问题:如果对缺少的属性属性的访问导致异常,让我们在 hybrid_propery 上设置属性字段,如下:

    @hybrid_property
    def key_id(self):
        return int(self.key.split('-')[1])
    
    @key_id.expression
    def key_id(cls):
        return cast(func.split_part(cls.key, '-', 2), Integer)
    
    key_id.__setattr__("property", "None")
    

【讨论】:

设置属性的奇怪方式有什么原因吗?为什么不:key_id.property = None 无特殊原因。只是为了“突出”解决方法而更加明确。

以上是关于在我的模型中,flask-restless 不适用于混合属性的主要内容,如果未能解决你的问题,请参考以下文章

Flask-restless 创建带有 unicode 字段的模型

是否可以扩展 Flask-restless 以添加新路线?

flask-restless validation_exceptions 不适用于 flask-sqlalchemy 模型中的少数列

如何使用 Flask-Restless 按日期搜索模型

使用 flask-restless 创建 API 响应

使用 flask-restless 对 POST 的错误请求与关系