CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pony

Pony Object-Relational Mapper for Python with Pythonic query syntax using generator expressions

Pending
Overview
Eval results
Files

attributes-relationships.mddocs/

Entity Attributes and Relationships

Attribute types for defining entity properties, primary keys, and relationships between entities. These classes define the schema structure, constraints, and relational mappings that form the foundation of the ORM.

Capabilities

Core Attribute Types

Basic attribute types for defining entity properties with various constraints and database column configurations.

class Required:
    def __init__(self, py_type, *args, **kwargs):
        """Define required (non-nullable) attribute.
        
        Args:
            py_type: Python type (str, int, float, datetime, etc.)
            *args: Additional constraints or default value
            **kwargs: Attribute options
                max_len: Maximum length for strings
                min: Minimum value for numbers
                max: Maximum value for numbers
                unique: Unique constraint
                index: Create database index
                default: Default value or callable
                sql_type: Override SQL column type
                column: Custom database column name
        """

class Optional:
    def __init__(self, py_type, *args, **kwargs):
        """Define optional (nullable) attribute.
        
        Args:
            py_type: Python type (str, int, float, datetime, etc.)
            *args: Additional constraints or default value
            **kwargs: Same options as Required
        """

class PrimaryKey:
    def __init__(self, py_type, *args, **kwargs):
        """Define primary key attribute.
        
        Args:
            py_type: Python type (usually int)
            *args: Additional constraints
            **kwargs: Attribute options
                auto: Auto-increment for integer keys (default True)
                size: Size for integer keys (32 or 64 bit)
        """

class Discriminator:
    def __init__(self, py_type, *args, **kwargs):
        """Define discriminator column for entity inheritance.
        
        Args:
            py_type: Python type (usually str or int)
            *args: Additional constraints
            **kwargs: Attribute options
        """

Relationship Attributes

Relationship types for defining connections between entities, supporting one-to-one, one-to-many, and many-to-many relationships.

class Set:
    def __init__(self, py_type, *args, **kwargs):
        """Define collection relationship (one-to-many or many-to-many).
        
        Args:
            py_type: Related entity class or string name
            *args: Additional relationship constraints
            **kwargs: Relationship options
                reverse: Name of reverse relationship attribute
                cascade_delete: Delete related objects when this is deleted
                lazy: Lazy loading behavior
                table: Join table name for many-to-many
                column: Foreign key column name
                reverse_column: Reverse foreign key column name
        """
        
    def add(self, item):
        """Add item to collection."""
        
    def remove(self, item):
        """Remove item from collection."""
        
    def clear(self):
        """Remove all items from collection."""
        
    def count(self):
        """Get count of items in collection."""
        
    def is_empty(self):
        """Check if collection is empty."""
        
    def select(self, lambda_expr=None):
        """Select items from collection matching criteria."""
        
    def filter(self, lambda_expr):
        """Filter collection items."""
        
    def order_by(self, *args):
        """Order collection items."""
        
    def random(self, limit):
        """Get random items from collection."""

class Reference:
    def __init__(self, py_type, *args, **kwargs):
        """Define reference to single related entity (one-to-one or many-to-one).
        
        Args:
            py_type: Related entity class or string name
            *args: Additional constraints
            **kwargs: Reference options
                reverse: Name of reverse relationship attribute
                cascade_delete: Delete behavior
                lazy: Lazy loading behavior
                column: Foreign key column name
        """

Composite Keys and Indexes

Functions for defining composite primary keys and database indexes across multiple attributes.

def composite_key(*attrs):
    """Define composite primary key from multiple attributes.
    
    Args:
        *attrs: Attribute instances to include in composite key
        
    Usage:
        class Person(db.Entity):
            first_name = Required(str)
            last_name = Required(str)
            birth_date = Required(date)
            composite_key(first_name, last_name, birth_date)
    """

def composite_index(*attrs, **kwargs):
    """Define composite database index across multiple attributes.
    
    Args:
        *attrs: Attribute instances to include in index
        **kwargs: Index options
            unique: Create unique index
            name: Custom index name
            
    Usage:
        class Person(db.Entity):
            first_name = Required(str)
            last_name = Required(str)
            email = Required(str)
            composite_index(first_name, last_name)
            composite_index(email, unique=True)
    """

Usage Examples

Basic Attributes

from pony.orm import *
from datetime import datetime, date

db = Database()

class Person(db.Entity):
    # Primary key (auto-increment by default)
    id = PrimaryKey(int)
    
    # Required attributes with constraints
    name = Required(str, max_len=100)
    email = Required(str, unique=True, max_len=255)
    age = Required(int, min=0, max=150)
    
    # Optional attributes
    phone = Optional(str, max_len=20)
    birth_date = Optional(date)
    salary = Optional(float, min=0)
    
    # Attribute with default value
    created_at = Required(datetime, default=datetime.now)
    is_active = Required(bool, default=True)
    
    # Custom column name and SQL type
    full_name = Optional(str, column='full_name_col', sql_type='VARCHAR(200)')
    
    # Indexed attribute
    department = Optional(str, index=True)

Relationships

class Company(db.Entity):
    name = Required(str, unique=True)
    founded = Optional(date)
    employees = Set('Employee')  # One-to-many
    
class Employee(db.Entity):
    name = Required(str)
    company = Required(Company)  # Many-to-one (reverse of employees)
    projects = Set('Project')    # Many-to-many
    manager = Optional('Employee')  # Self-reference
    subordinates = Set('Employee', reverse='manager')  # Reverse self-reference
    
class Project(db.Entity):
    name = Required(str)
    employees = Set(Employee)    # Many-to-many (reverse of projects)
    deadline = Optional(date)

Advanced Relationship Configuration

class Author(db.Entity):
    name = Required(str)
    books = Set('Book', cascade_delete=True)  # Delete books when author deleted
    
class Book(db.Entity):
    title = Required(str)
    isbn = Required(str, unique=True)
    author = Required(Author)
    tags = Set('Tag', table='book_tags', 
              column='book_id', reverse_column='tag_id')  # Custom join table
    
class Tag(db.Entity):
    name = Required(str, unique=True)
    books = Set(Book)

# Entity inheritance with discriminator
class Vehicle(db.Entity):
    make = Required(str)
    model = Required(str)
    year = Required(int)
    vehicle_type = Discriminator(str)  # Discriminator for inheritance

class Car(Vehicle):
    doors = Required(int)
    
class Motorcycle(Vehicle):
    engine_size = Required(int)

Composite Keys and Indexes

class OrderItem(db.Entity):
    order_id = Required(int)
    product_id = Required(int) 
    quantity = Required(int)
    price = Required(float)
    
    # Composite primary key
    composite_key(order_id, product_id)
    
class Person(db.Entity):
    first_name = Required(str)
    last_name = Required(str)
    email = Required(str)
    birth_date = Optional(date)
    
    # Composite indexes
    composite_index(first_name, last_name)  # For name searches
    composite_index(email, unique=True)     # Unique email index
    composite_index(birth_date, last_name)  # For birthday queries

Working with Collections

with db_session:
    # Create entities with relationships
    company = Company(name="Tech Corp", founded=date(2020, 1, 1))
    
    # Add employees to company
    alice = Employee(name="Alice", company=company)
    bob = Employee(name="Bob", company=company)
    
    # Working with Set collections
    print(f"Company has {company.employees.count()} employees")
    
    # Add to collection  
    company.employees.add(Employee(name="Charlie", company=company))
    
    # Filter collection
    senior_employees = company.employees.select(lambda e: e.salary > 80000)
    
    # Order collection
    ordered_employees = company.employees.order_by(Employee.name)
    
    # Many-to-many relationships
    project = Project(name="Website Redesign")
    project.employees.add(alice)
    project.employees.add(bob)
    
    # Access reverse relationship
    alice_projects = alice.projects  # All projects Alice works on

Install with Tessl CLI

npx tessl i tessl/pypi-pony

docs

aggregations-helpers.md

attributes-relationships.md

data-types.md

database-entities.md

debugging-utilities.md

exception-handling.md

framework-integrations.md

index.md

query-operations.md

security-permissions.md

session-management.md

tile.json