Skip to content

Field

A Field attribute represents a single column on a relation. halfORM exposes all columns automatically as Field instances on every relation object.

Two usage patterns:

  • Read — inspect the current constraint value or schema metadata: field.value, field.name, field.py_type, field.is_set(), field.is_not_null().
  • Write — constrain the field to filter rows: field.set(value), field.set((comp, value)).

Constraints are usually set via keyword arguments when instantiating a relation, but .set() is useful when you need a non-= comparator, unaccent, a column-to-column comparison, or an arithmetic expression:

author = Author()
author.last_name.set(('ilike', 'mar%'), unaccent=True)

post = Post()
post.views.set(('>', post.likes))                       # WHERE views > likes
post.views.set(('>=', Expr('2 * "likes"')))             # WHERE views >= 2 * likes

Setting any field to None removes that constraint.

See Learn halfORM in half an hour for a full walkthrough of filtering and comparators.


SQL expressions

Expr

A raw SQL expression for use with :meth:Field.set.

Quoted column identifiers ("col") are automatically prefixed with the relation alias in SELECT queries. String literals use single quotes in SQL, so double-quoted tokens are unambiguously column references.

Use this when you need arithmetic or any SQL expression that column-to-column :meth:Field.set cannot express::

from half_orm.field import Expr

p = Post()
p.views.set(('>=', Expr('2 * "likes"')))       # views >= 2 * likes
p.score.set(Expr('"likes" * 10 + "views"'))    # score = likes*10 + views

Constraint

set(*args, unaccent=False)

Constrain this field, optionally with a custom comparator.

Parameters

value : The constraint value. Pass None to remove the constraint. Pass a (comparator, value) tuple to use an operator other than =. Supported comparators: =, !=, <, <=, >, >=, like, ilike, in, is, is not, and any other PostgreSQL operator accepted in a WHERE clause.

Pass a sibling ``Field`` of the **same** relation instance, or an
:class:`Expr` for arbitrary SQL expressions, to compare columns of
the same table without bound parameters.
bool

When True, wraps both sides in PostgreSQL unaccent() before comparing. Requires the unaccent extension.

Examples::

a = Author()
a.last_name.set('Martin')               # last_name = 'Martin'
a.last_name.set(('ilike', 'mar%'))       # last_name ILIKE 'mar%'
a.last_name.set(('ilike', 'mar%'), unaccent=True)
                                        # unaccent(last_name) ILIKE unaccent('mar%')

from half_orm.null import NULL
a.last_name.set(NULL)                   # last_name IS NULL
a.last_name.set(('is not', NULL))        # last_name IS NOT NULL

a.last_name.set(None)                   # removes the constraint

# Column-to-column (same relation instance)
p = Post()
p.views.set(p.likes)                              # views = likes
p.views.set(('>', p.likes))                       # views > likes

# Arbitrary SQL expression
from half_orm.field import Expr
p.views.set(('>=', Expr('2 * "likes"')))          # views >= 2 * likes
p.score.set(Expr('"likes" * 10 + "views"'))       # score = likes*10 + views

Inspection

is_set()

Return True if this field currently carries a constraint.

A field is set after a call to :meth:set with a non-None value, or when the relation was instantiated with a keyword argument for this column. Setting the value back to None clears the constraint.

Example::

a = Author()
a.last_name.is_set()              # False
a.last_name.set('Martin')
a.last_name.is_set()              # True
a.last_name.set(None)
a.last_name.is_set()              # False

value property

The current constraint value, or None if the field is not set.

Use this to read back a value that was set on a row returned by :meth:~half_orm.relation.Relation.ho_get or extracted from an :meth:~half_orm.relation.Relation.ho_select result::

author = Author(last_name='Martin').ho_get()
author.last_name.value    # 'Martin'
author.first_name.value   # 'Alice'

name property

The column name as it appears in the database.

py_type property

The Python type that maps to this column's SQL type.

Array columns (PostgreSQL _type) are returned as typing.List[inner_type]. Unknown SQL types fall back to typing.Any.

Example::

Author().last_name.py_type   # <class 'str'>
Post().tags.py_type          # typing.List[str]  (if tags is text[])

is_not_null()

Return True if the column is declared NOT NULL in the schema.

This reflects the database constraint, not the current value.

Example::

Author().last_name.is_not_null()   # True  (declared NOT NULL)
Author().email.is_not_null()       # True
Post().content.is_not_null()       # False (nullable column)

unaccent property writable

Whether unaccent() is applied to this field's comparison.

Can also be set via the unaccent keyword argument of :meth:set. Requires the PostgreSQL unaccent extension to be installed.