from flask_sqlalchemy import SQLAlchemy from sqlalchemy import Enum, Integer, Float, String, Date, Column, Boolean from config import item_attributes, sql_conf from definitions.attributes import * from werkzeug.security import generate_password_hash, check_password_hash # Initialize SQLAlchemy db = SQLAlchemy() # Users table class User(db.Model): """User model for authentication.""" __tablename__ = "users_test" id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(50), unique=True, nullable=False) password_hash = db.Column(db.String(256), nullable=False) # Increase length to 256 def set_password(self, password: str) -> None: """Hash the password and store it.""" self.password_hash = generate_password_hash(password) def check_password(self, password: str) -> bool: """Check if the provided password matches the stored hash.""" return check_password_hash(self.password_hash, password) # Mapping of attribute types to SQLAlchemy column types COLUMN_TYPE_MAPPING = { textAttribute: lambda attrib: String(attrib.max_length), # Map text attributes to String columns dateAttribute: lambda attrib: Date, # Map date attributes to Date columns selectAttribute: lambda attrib: Enum(*attrib.options), # Map select attributes to Enum columns intAttribute: lambda attrib: Integer, # Map integer attributes to Integer columns floatAttribute: lambda attrib: Float, # Map float attributes to Float columns } def _get_column_type(attrib): """Helper function to get the SQLAlchemy column type for an attribute.""" if type(attrib) not in COLUMN_TYPE_MAPPING: raise ValueError( f"Unsupported attribute type: {type(attrib)} for attribute '{attrib.attrib_name}'. " f"Supported types are: {list(COLUMN_TYPE_MAPPING.keys())}" ) return COLUMN_TYPE_MAPPING[type(attrib)](attrib) def _get_column_properties(attrib): """Helper function to get the properties for a column.""" return { 'primary_key': attrib.primary, 'unique': attrib.unique, 'nullable': not attrib.required, 'default': attrib.default_val } def create_asset_model(): """ Dynamically creates the Asset model based on the configuration in item_attributes. """ # Define the table name and basic methods attrs = { '__tablename__': sql_conf.SQL_TABLE, '__init__': lambda self, **kwargs: self.__dict__.update(kwargs), # Allow dynamic assignment of attributes '__repr__': lambda self: f"" # Provide a readable representation of the object } # Define columns based on item_attributes for attrib in item_attributes: column_type = _get_column_type(attrib) column_properties = _get_column_properties(attrib) attrs[attrib.attrib_name] = Column(column_type, **column_properties) # Create the Item class dynamically Item = type('Item', (db.Model,), attrs) return Item # Create the Item model Asset = create_asset_model()