Advanced ORM Features#
Asok's ORM is designed to be powerful yet lightweight. This guide covers advanced field types and query patterns added for professional applications.
1. Advanced Field Types#
JSON Field#
Store complex data structures (dicts, lists) transparently.
from asok import Model, Field
class Settings(Model):
config = Field.JSON(default={})
# Usage
s = Settings.create(config={"theme": "dark", "notifications": True})
print(s.config["theme"]) # "dark" (automatically a dict)
Enum Field#
Integrate with Python's standard enum.Enum for type-safe choices.
import enum
from asok import Model, Field
class Status(enum.Enum):
PENDING = "pending"
ACTIVE = "active"
class User(Model):
status = Field.Enum(Status, default=Status.PENDING)
Decimal Field#
Precise math for financial data (money).
from decimal import Decimal
from asok import Model, Field
class Product(Model):
price = Field.Decimal(precision=2)
p = Product.create(price=Decimal("19.99"))
UUID Field#
Automatically generate unique identifiers.
from asok import Model, Field
class Job(Model):
uid = Field.UUID() # Auto-generates uuid4 on save
Tel / Phone Field#
Store validated phone numbers.
from asok import Model, Field
class User(Model):
phone = Field.Tel(unique=True)
Rich Text (WYSIWYG)#
Upgrade standard textareas to a full-featured editor in the admin panel.
from asok import Model, Field
class Post(Model):
body = Field.Text(wysiwyg=True) # Enables Quill editor in Admin
2. Advanced Querying#
OR Conditions#
User.query().where("status", "active").or_where("is_admin", True).get()
Range & NULL Checks#
# Between
Product.query().where_between("price", 10, 50).get()
# NULL checks
User.query().where_null("deleted_at").get()
User.query().where_not_null("email_verified_at").get()
Sorting Shorthands#
latest_users = User.query().latest().limit(5).get()
oldest_tasks = Task.query().oldest().get()
3. Native Vector Search (Semantic)#
Asok supports storing and searching high-dimensional vectors (embeddings) directly in SQLite using specialized binary storage and custom similarity functions.
Defining a Vector Field#
Specify the dimensions of your embedding (e.g., 1536 for OpenAI, 384 for standard local models).
from asok import Model, Field
class Document(Model):
content = Field.String()
embedding = Field.Vector(dimensions=1536)
Proximity Searching#
Use .nearest() to find rows most similar to a query vector.
query_vec = [0.1, 0.5, ...] # List of floats
docs = Document.query().nearest("embedding", query_vec, metric="cosine", limit=5).get()
Metrics supported: cosine (default) and euclidean.
Admin Integration#
You can enable semantic search in the Admin search bar! 1. Add vector_search_field to your Admin class. 2. Define an embed_query method on your model to convert search text into a vector.
from asok import Model, Field
class Product(Model):
name = Field.String()
vec = Field.Vector(1536)
@classmethod
def embed_query(cls, text):
# Call OpenAI / Mistral / Local model here
return [0.1, 0.2, ...]
class Admin:
search_fields = ["name"]
vector_search_field = "vec"
4. High-Performance Model Methods#
Atomic Increments/Decrements#
Safely update counters directly in SQL to avoid race conditions.
post = Post.find(1)
post.increment("views") # SQL: UPDATE posts SET views = views + 1 ...
Reloading Data#
post.refresh() # Reloads attributes from the database
API Error Handling#
Perfect for REST controllers:
from asok import Request, ModelError
def get(request: Request):
try:
user = User.find_or_fail(request.params["id"])
return request.api(user.to_dict())
except ModelError:
return request.api_error("User not found", status=404)
Was this page helpful?