base.py
1 """Base model for all database models.""" 2 from datetime import datetime 3 from typing import Any, Dict, List, Optional, Type, TypeVar, Generic 4 5 from sqlalchemy import Column, DateTime 6 from sqlalchemy.ext.declarative import as_declarative, declared_attr 7 from sqlalchemy.orm import Session 8 9 ModelType = TypeVar("ModelType", bound="Base") 10 11 @as_declarative() 12 class Base: 13 """Base model that includes common columns and methods.""" 14 15 id: Any 16 __name__: str 17 18 # Auto-generate __tablename__ from class name 19 @declared_attr 20 def __tablename__(cls) -> str: 21 return cls.__name__.lower() 22 23 # Timestamps 24 created_at = Column(DateTime, default=datetime.utcnow, nullable=False) 25 updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) 26 27 def to_dict(self) -> Dict[str, Any]: 28 """Convert model instance to dictionary.""" 29 return { 30 column.name: getattr(self, column.name) 31 for column in self.__table__.columns # type: ignore 32 } 33 34 @classmethod 35 def create(cls, db: Session, **kwargs) -> ModelType: 36 """Create a new record in the database.""" 37 instance = cls(**kwargs) 38 db.add(instance) 39 db.commit() 40 db.refresh(instance) 41 return instance 42 43 @classmethod 44 def get(cls, db: Session, id: Any) -> Optional[ModelType]: 45 """Get a record by ID.""" 46 return db.query(cls).filter(cls.id == id).first() 47 48 @classmethod 49 def get_multi( 50 cls, db: Session, *, skip: int = 0, limit: int = 100 51 ) -> List[ModelType]: 52 """Get multiple records with pagination.""" 53 return db.query(cls).offset(skip).limit(limit).all() 54 55 def update(self, db: Session, **kwargs) -> None: 56 """Update record with given values.""" 57 for field, value in kwargs.items(): 58 if hasattr(self, field): 59 setattr(self, field, value) 60 db.add(self) 61 db.commit() 62 db.refresh(self) 63 64 def delete(self, db: Session) -> None: 65 """Delete the record from the database.""" 66 db.delete(self) 67 db.commit()