flask-restless dont work with hybrid property in my models

626 views Asked by At

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

1

There are 1 answers

2
Eliran Shem Tov On

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")