Visitors¶
Therismos uses the visitor pattern for extensible backend conversions.
Custom Visitors¶
Implement ExprVisitor to convert expressions to any format:
from therismos import ExprVisitor
class SQLVisitor:
def visit_eq(self, expr):
return f"{expr.field.name} = ?"
def visit_all(self, expr):
parts = [e.accept(self) for e in expr.exprs]
return " AND ".join(parts)
# ... implement other visit methods
visitor = SQLVisitor()
sql = expr.accept(visitor)
Built-in Visitors¶
StringVisitor¶
Converts expressions to human-readable strings:
from therismos import F, StringVisitor
age = F("age")
name = F("name")
expr = (age > 18) & (name == "Alice")
visitor = StringVisitor()
result = expr.accept(visitor)
# Output: "(age > 18 AND name = 'Alice')"
CountVisitor¶
Counts the number of nodes in an expression tree:
from therismos import F, CountVisitor
expr = (age > 18) & (name == "Alice")
count = expr.accept(CountVisitor())
# Output: 3 (1 AllExpr + 2 atomic expressions)
DictVisitor¶
Converts expressions to a dictionary representation:
from therismos import F, DictVisitor
expr = age > 18
result = expr.accept(DictVisitor())
# {"type": "gt", "field": "age", "value": 18}
expr = (age > 18) & (name == "Alice")
result = expr.accept(DictVisitor())
# {
# "type": "and",
# "exprs": [
# {"type": "gt", "field": "age", "value": 18},
# {"type": "eq", "field": "name", "value": "Alice"}
# ]
# }
FieldGathererVisitor¶
Collects all unique field names used in an expression tree:
from therismos import F, FieldGathererVisitor
age = F("age")
name = F("name")
status = F("status")
expr = (age > 18) & (name == "Alice") | (status == "active")
visitor = FieldGathererVisitor()
expr.accept(visitor)
field_names = visitor.field_names
# {"age", "name", "status"}
Useful for validating that all referenced fields exist in your schema, determining required permissions, or generating metadata.
Backend Visitors¶
- MongoDB —
MongoVisitor - SQLAlchemy / SQLModel —
SQLAlchemyExprVisitor - Polars —
PolarsExprVisitor - pandas —
PandasExprVisitor