Micheal J. Roberts
Micheal J. Roberts

Reputation: 4180

hybrid_expressions in SQLAlchemy with arguments

I currently have the following hybrid_property and hybrid_property.expression() on a model I have outlined:

class Body():

    @hybrid_property
    def altitude(self, LST: float, latitude: float) -> float:
        return self.get_altitude(LST, latitude)

    @altitude.expression
    def altitude(cls, LST: float, latitude: float) -> float:
        """
        Get the altitude of the star as a raw SQL expressions
        """
        ha = (LST - cls.ra) % 360

        ra = func.radians(ha)

        dec = func.radians(cls.dec)

        lat = func.radians(latitude)

        alt = func.asin(
            func.sin(dec) * func.sin(lat) + func.cos(dec) * func.cos(lat) * func.cos(ra)
        )

        return func.degrees(alt)

However, when I attempt to use this within a SQLAlchemy filter as:

query = query.filter(self.model.altitude(LST, latitude) > 0)

I get the following error:

TypeError: altitude() missing 2 required positional arguments: 'LST' and 'latitude'

Even though these are both defined.

Upvotes: 0

Views: 285

Answers (1)

rfkortekaas
rfkortekaas

Reputation: 6514

You are looking for a hybrid_method, the hybrid_property doesn't support arguments.

class Body():

    @hybrid_method
    def altitude(self, LST: float, latitude: float) -> float:
        return self.get_altitude(LST, latitude)

    @altitude.expression
    def altitude(self, LST: float, latitude: float) -> float:
        """
        Get the altitude of the star as a raw SQL expressions
        """
        ha = (LST - cls.ra) % 360

        ra = func.radians(ha)

        dec = func.radians(cls.dec)

        lat = func.radians(latitude)

        alt = func.asin(
            func.sin(dec) * func.sin(lat) + func.cos(dec) * func.cos(lat) * func.cos(ra)
        )

        return func.degrees(alt)

Upvotes: 2

Related Questions