I am working on my preliminary tables, my understanding is using Mapped and mapped_column is a more modern approach, I could be mistaken however, take a look and do it step-by-step to provide me detailed feedback:

```
# Database portion

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session

DATABASE_URL = "sqlite+pysqlite:///./dili.db"
MEMORY_URL = "sqlite+pysqlite:///:memory:"

engine = create_engine(
    MEMORY_URL,
    connect_args={"check_same_thread": False},
    echo=True
)

SessionLocal = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))

# Global DB access
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


from sqlalchemy import DateTime, func, String, Integer, ForeignKey, UniqueConstraint
from sqlalchemy.orm import declarative_base, Mapped, mapped_column

# Core Model
Model = declarative_base()
Model.query = SessionLocal.query_property()

class TimeStampedModel(Model):
    """
    Tell my dumbass I missed a docstring.
    """
    __abstract__ = True

    created_at = mapped_column(DateTime(timezone=True), default=func.now())
    updated_at = mapped_column(DateTime(timezone=True), default=func.now(), onupdate=func.now())

"""
TEMPLATE:

class (TimeStampedModel):
"""
"""
    __tablename__ = ""

    # columns

    # relationships

    # methods
    def __repr__(self):
        return f"{self.__tablename__!r}(id={self.id!r})"
"""

class Fingerprint(TimeStampedModel):
    """
    Tell my dumbass I missed a docstring.
    """
    __tablename__ = "fingerprints"

    # columns
    fingerprint: Mapped[str] = mapped_column(String(128), primary_key=True)
    size: Mapped[int] = mapped_column(Integer)

    # relationships

    # methods
    def __repr__(self):
        return f"{self.__tablename__!r}(fingerprint={self.fingerprint!r}, size={self.size!r})"

class HashType(TimeStampedModel):
    """
    Tell my dumbass I missed a docstring.
    """
    __tablename__ = "hash_types"

    # columns
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    name: Mapped[str] = mapped_column(String(50))

    # relationships

    # methods
    def __repr__(self):
        return f"{self.__tablename__!r}(id={self.id!r}, name={self.name!r})"

class Hash(TimeStampedModel):
    """
    Tell my dumbass I missed a docstring.
    """
    __tablename__ = "hashes"

    # columns
    fingerprint: Mapped[str] = mapped_column(ForeignKey(Fingerprint.fingerprint), primary_key=True)
    hash_type_id: Mapped[int] = mapped_column(ForeignKey(HashType.id))
    hash: Mapped[str] = mapped_column(String(256), index=True)

    # relationships
    __table_args__ = (
        UniqueConstraint(fingerprint, hash_type_id)
    )

    # methods
    def __repr__(self):
        return f"{self.__tablename__!r}(fingerprint={self.fingerprint!r}, hash_type_id={self.hash_type_id!r}, hash={self.hash!r})"


class File(TimeStampedModel):
    """
    Tell my dumbass I missed a docstring.
    """
    __tablename__ = "files"

    # columns
    id: Mapped[int] = mapped_column(primary_key=True)
    path: Mapped[str] = mapped_column(index=True)
    type: Mapped[str] = mapped_column(String(100), index=True) # We want to store MIME typing here
    size: Mapped[int]
    file_created_at = mapped_column(DateTime(timezone=True))
    file_updated_at = mapped_column(DateTime(timezone=True))

    # relationships

    # methods
    def __repr__(self):
        return f"{self.__tablename__!r}(id={self.id!r}, path=`{self.path!r}`, type={self.type!r}, size={self.size!r}, file_created_at={self.file_created_at!r}, file_updated_at={self.file_updated_at!r})"


# In order to actually create the tables:
Model.metadata.create_all(engine)
```