1

I am create api for our front-end dev and i have problem with objects in my model. I use flask-sqlalchemy and python2.7

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

ORM model

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 

Exception

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 -

i dont know what happens and i cant find the solved in google. Thank you and sorry for my english

PS: this flask plugin work fine without hybrid property in model but hybrid columns important for my project

bilyk max
  • 11
  • 1
  • What version of Flask-Restless are you using? The file [*helpers.py*](https://github.com/jfinkels/flask-restless/blob/master/flask_restless/helpers.py) from your traceback does not match the one in Github, at least. The version in Github does the right thing(tm) in `primary_key_names()` and uses `mapper.primary_key` instead of inspecting attributes directly. – Ilja Everilä Jan 10 '18 at 07:40
  • 1
    i am use the 0.17.0 version of Flask-Restless because last version is Beta(1.0.0b1). The author recommends using a stable version i.e 0.17.0 Thank you, I will read more documentations. – bilyk max Jan 11 '18 at 13:28

1 Answers1

0

As it seems, this is a known bug in the Flask-Restless project and not in flask-sqlalchemy.

It was already fixed on the master branch but there is no current stable version that implemented the solution.

The root cause of the problem is in flask-restless's helpers.py file, in the "primary_key_names" which attempts to access a field called property, of the hybrid_property object. Since it does not exist, an exception is raised.

Possible solutions:

  1. Set the dependency on the master branch of Flask-Restless. This solution is not that good IMO, as it is somewhat temporary (future changes may break your code).
  2. Fork the repo and implement the solution proposed in the original github issue.
  3. The solution that I chose to implement on my side is to work around the issue on my code: if the access to the missing property attribute causes the exception, lets set property field on the hybrid_propery, as follows:

    @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")
    
Eliran Shem Tov
  • 558
  • 5
  • 15