The hybrid attribute gets its name from the fact that the attribute will behave differently depending on whether it is accessed via the Interval class or an Interval instance.

    If accessed via an instance, then it behaves just as you would expect.

    If accessed via the Interval.length class attribute, however, the length calculation will be expressed as a SQL expression. For example:

    1. query = Interval.select().where(Interval.length > 5)

    This query will be equivalent to the following SQL:

    1. SELECT "t1"."id", "t1"."start", "t1"."end"
    2. FROM "interval" AS t1
    3. WHERE (("t1"."end" - "t1"."start") > 5)

    The playhouse.hybrid module also contains a decorator for implementing hybrid methods which can accept parameters. As with hybrid properties, when accessed via a model instance, then the function executes normally as-written. When the hybrid method is called on the class, however, it will generate a SQL expression.

    Example:

    1. query = Interval.select().where(Interval.contains(2))

    This query is equivalent to the following SQL:

    1. class Interval(Model):
    2. start = IntegerField()
    3. end = IntegerField()
    4. @hybrid_property
    5. def length(self):
    6. return self.end - self.start
    7. @hybrid_property
    8. @radius.expression
    9. def radius(cls):
    10. return fn.ABS(cls.length) / 2

    What is neat is that both the radius implementations refer to the length hybrid attribute! When accessed via an Interval instance, the radius calculation will be executed in Python. When invoked via an Interval class, we will get the appropriate SQL.

    Example:

    1. query = Interval.select().where(Interval.radius < 3)

    This query is equivalent to the following SQL:

    1. SELECT "t1"."id", "t1"."start", "t1"."end"
    2. FROM "interval" AS t1
    3. WHERE ((abs("t1"."end" - "t1"."start") / 2) < 3)

    Pretty neat, right? Thanks for the cool idea, SQLAlchemy!

    class hybrid_method(func[, expr=None])

    Method decorator that allows the definition of a Python object method with both instance-level and class-level behavior.

    Example:

    1. query = Interval.select().where(Interval.contains(2))

    Would generate the following SQL:

    1. SELECT "t1"."id", "t1"."start", "t1"."end"
    2. FROM "interval" AS t1
    3. WHERE (("t1"."start" <= 2) AND (2 < "t1"."end"))
    • expression(expr)

      Method decorator for specifying the SQL-expression producing method.

    class hybrid_property(fget[, fset=None[, fdel=None[, expr=None]]])

    Method decorator that allows the definition of a Python object property with both instance-level and class-level behavior.

    Examples:

    1. start = IntegerField()
    2. end = IntegerField()
    3. @hybrid_property
    4. def length(self):
    5. return self.end - self.start
    6. @hybrid_property
    7. def radius(self):
    8. return abs(self.length) / 2
    9. @radius.expression
    10. def radius(cls):
    11. return fn.ABS(cls.length) / 2

    When accessed on an Interval instance, the length and radius properties will behave as you would expect. When accessed as class attributes, though, a SQL expression will be generated instead:

    1. SELECT "t1"."id", "t1"."start", "t1"."end"
    2. FROM "interval" AS t1
    3. WHERE (
    4. (("t1"."end" - "t1"."start") > 6) AND
    5. ((abs("t1"."end" - "t1"."start") / 2) >= 3)