Files
stl-repo/app/models.py
Consultoria AS 14b307110d feat: implementar 12 mejoras, tests, docs y optimizaciones
- Fase A: license templates, search history, cost estimator
- Fase B: import URL, bulk ZIP, batch download
- Fase C: comparison mode, mesh validation, measurement tool
- Fase D: cross-section clipping, overhang heatmap, layer animation
- Refactor Pydantic/SQLAlchemy warnings
- 24 tests pytest
- README actualizado
- WebP thumbnails, lazy loading, cache headers
2026-04-27 09:14:58 +00:00

106 lines
3.8 KiB
Python

from sqlalchemy import Column, Integer, String, Float, DateTime, Text, Boolean, Table, ForeignKey
from sqlalchemy.orm import relationship
from datetime import datetime, timezone
from app.database import Base
# Many-to-many association tables
model_tags = Table(
'model_tags',
Base.metadata,
Column('model_id', Integer, ForeignKey('models.id'), primary_key=True),
Column('tag_id', Integer, ForeignKey('tags.id'), primary_key=True)
)
collection_models = Table(
'collection_models',
Base.metadata,
Column('collection_id', Integer, ForeignKey('collections.id'), primary_key=True),
Column('model_id', Integer, ForeignKey('models.id'), primary_key=True)
)
class Tag(Base):
__tablename__ = "tags"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, unique=True, nullable=False, index=True)
models = relationship("Model3D", secondary=model_tags, back_populates="tags")
class Model3D(Base):
__tablename__ = "models"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, nullable=False)
filename = Column(String, nullable=False)
description = Column(Text, nullable=True)
author = Column(String, nullable=True)
license = Column(String, nullable=True)
category = Column(String, nullable=True)
file_size = Column(Integer, nullable=True)
file_hash = Column(String, nullable=True, index=True)
width = Column(Float, nullable=True)
height = Column(Float, nullable=True)
depth = Column(Float, nullable=True)
faces = Column(Integer, nullable=True)
created_at = Column(DateTime, default=datetime.now(timezone.utc))
thumbnail_path = Column(String, nullable=True)
download_count = Column(Integer, default=0)
tags = relationship("Tag", secondary=model_tags, back_populates="models")
files = relationship("ModelFile", back_populates="model", cascade="all, delete-orphan")
ratings = relationship("Rating", back_populates="model", cascade="all, delete-orphan")
comments = relationship("Comment", back_populates="model", cascade="all, delete-orphan")
collections = relationship("Collection", secondary=collection_models, back_populates="models")
class ModelFile(Base):
__tablename__ = "model_files"
id = Column(Integer, primary_key=True, index=True)
model_id = Column(Integer, ForeignKey("models.id"), nullable=False)
filename = Column(String, nullable=False)
file_path = Column(String, nullable=False)
file_type = Column(String, nullable=False, default='stl')
part_name = Column(String, nullable=True)
is_primary = Column(Boolean, default=False)
file_size = Column(Integer, nullable=True)
file_hash = Column(String, nullable=True)
model = relationship("Model3D", back_populates="files")
class Rating(Base):
__tablename__ = "ratings"
id = Column(Integer, primary_key=True, index=True)
model_id = Column(Integer, ForeignKey("models.id"), nullable=False)
stars = Column(Integer, nullable=False) # 1-5
created_at = Column(DateTime, default=datetime.now(timezone.utc))
model = relationship("Model3D", back_populates="ratings")
class Collection(Base):
__tablename__ = "collections"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
description = Column(Text, nullable=True)
created_at = Column(DateTime, default=datetime.now(timezone.utc))
models = relationship("Model3D", secondary=collection_models, back_populates="collections")
class Comment(Base):
__tablename__ = "comments"
id = Column(Integer, primary_key=True, index=True)
model_id = Column(Integer, ForeignKey("models.id"), nullable=False)
author_name = Column(String, nullable=True)
text = Column(Text, nullable=False)
created_at = Column(DateTime, default=datetime.now(timezone.utc))
model = relationship("Model3D", back_populates="comments")