feat(models): implementación de esquema de base de datos y entidades SQLAlchemy#4
Merged
Merged
Conversation
…, alert, and trend_snapshot
There was a problem hiding this comment.
Pull request overview
Este PR implementa la capa de datos del backend definiendo modelos SQLAlchemy que mapean el esquema ER (entidades principales, tablas asociativas y restricciones) para su uso con PostgreSQL, y centraliza la exportación de modelos desde app.models.
Changes:
- Se agregan modelos SQLAlchemy para entidades base y de dominio (Category, City, Skill, Job, User, etc.) con relaciones y restricciones (UNIQUE/CHECK/PK compuesta).
- Se define la tabla asociativa
JobSkillcon llave primaria compuesta y se agregan entidades analíticas comoTrendSnapshot. - Se expone un punto de importación único de modelos vía
backend/app/models/__init__.pyy se hace un ajuste menor de formato.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/app/models/user.py | Modelo User con constraint de roles y relaciones a alertas/respaldos. |
| backend/app/models/trend_snapshot.py | Modelo analítico TrendSnapshot con unicidad compuesta por skill/ciudad/fecha. |
| backend/app/models/skill.py | Modelo Skill con canonical_name único y relaciones a jobs/alertas/snapshots. |
| backend/app/models/job.py | Modelo Job con salarios, hash de descripción y relación con JobSkill. |
| backend/app/models/job_skill.py | Tabla asociativa JobSkill con PK compuesta (job_id, skill_id). |
| backend/app/models/city.py | Modelo City con default de país y relaciones a jobs/snapshots. |
| backend/app/models/category.py | Modelo Category y relación 1-N a skills. |
| backend/app/models/backup.py | Modelo Backup con constraint de status y FK opcional a usuario. |
| backend/app/models/alert.py | Modelo Alert (tabla user_alerts) con FKs a usuario y skill. |
| backend/app/models/init.py | Export centralizado de todos los modelos (__all__). |
| backend/app/init.py | Ajuste menor de formato (whitespace) en respuesta de health check. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| id = db.Column(db.Integer, primary_key=True) | ||
| name = db.Column(db.String(50), nullable=False, unique=True) | ||
|
|
||
| skills = db.relationship('Skill', backref='category', lazy=True) No newline at end of file |
Comment on lines
+9
to
+10
| # Establecemos México como default tanto a nivel aplicación como base de datos | ||
| country = db.Column(db.String(10), default='MX', server_default='MX', nullable=True) |
Comment on lines
+14
to
+15
| jobs = db.relationship('Job', backref='city', lazy=True) | ||
| trend_snapshots = db.relationship('TrendSnapshot', backref='city', lazy=True) No newline at end of file |
Comment on lines
+12
to
+14
| job_skills = db.relationship('JobSkill', backref='skill', lazy=True) | ||
| alerts = db.relationship('Alert', backref='skill', lazy=True) | ||
| trend_snapshots = db.relationship('TrendSnapshot', backref='skill', lazy=True) No newline at end of file |
| email = db.Column(db.String(255), unique=True, nullable=False) | ||
| password_hash = db.Column(db.String(255), nullable=False) | ||
| role = db.Column(db.String(20), nullable=False) | ||
| created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc)) |
Comment on lines
+21
to
+22
| created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc)) | ||
| updated_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) |
| created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc)) | ||
| updated_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) | ||
|
|
||
| job_skills = db.relationship('JobSkill', backref='job', lazy=True) No newline at end of file |
| skill_id = db.Column(db.Integer, db.ForeignKey('skills.id'), primary_key=True) | ||
|
|
||
| confidence_score = db.Column(db.Numeric(4, 3), nullable=False) | ||
| created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc)) No newline at end of file |
| user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) | ||
| filename = db.Column(db.String(255), nullable=False) | ||
| storage_url = db.Column(db.String(500), nullable=False) | ||
| created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc)) |
| skill_id = db.Column(db.Integer, db.ForeignKey('skills.id'), nullable=False) | ||
| threshold = db.Column(db.Integer, nullable=False) | ||
| active = db.Column(db.Boolean, default=True, nullable=False) | ||
| created_at = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc)) No newline at end of file |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feature/sqlalchemy-models
Descripción
Se implementa la capa de datos completa mapeando el diagrama Entidad-Relación oficial a modelos de SQLAlchemy. Este bloque establece la estructura base para la interacción con PostgreSQL, asegurando la integridad referencial, la Tercera Forma Normal (3FN) y la delegación de restricciones de negocio al motor de base de datos.
Decisiones técnicas integradas:
Category,City(conserver_default='MX'),User(roles restringidos víaCheckConstrainta nivel tabla).Skill(nombre canónico único),Job(description_hashpara rastreo de duplicidad,city_idnulo para vacantes remotas),Backup.JobSkill(llave primaria compuesta),Alert,TrendSnapshot(UniqueConstraintmulticampo para unicidad temporal y geográfica).app/models/__init__.py.Tipo de cambio
Cómo probar
git checkout develop && git pull origin developcd backendflask --app run shellfrom app.models import User, Job, Skill, TrendSnapshotexit().Checklist