не помнб

This commit is contained in:
ivankirpichnikov
2025-11-22 18:15:29 +03:00
parent 995141a200
commit effbcfbc2d
17 changed files with 210 additions and 54 deletions
@@ -15,7 +15,7 @@ class KeySkillsDataGateway:
async def query(self, query: str) -> Sequence[str]:
statement = (
select(key_skills_table.c.name)
.where(key_skills_table.c.name.ilike(f"{query}%"))
.where(key_skills_table.c.name.ilike(f"%{query}%"))
.order_by(key_skills_table.c.name)
.limit(30)
)
@@ -6,7 +6,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from template_project.adapters.data_gateways.tables import resume_prediction_table, resume_table
from template_project.application.resume.data_gateway import ResumeDataGateway, ResumePredictionDataGateway
from template_project.application.resume.entity import Resume, ResumeEmbeddingId, ResumeId, ResumePrediction
from template_project.application.resume.entity import Resume, ResumeId, ResumePrediction
from template_project.application.resume.errors import ResumeNotFoundError
from template_project.application.user.entity import UserId
@@ -15,10 +15,6 @@ class DefaultResumeDataGateway(ResumeDataGateway):
def __init__(self, session: AsyncSession) -> None:
self._session = session
@override
async def get_suitable_resumes(self, embedding_id: ResumeEmbeddingId) -> Sequence[Resume]:
raise NotImplementedError
@override
async def load(self, resume_id: ResumeId) -> Resume:
resume = await self._session.get(Resume, resume_id)
@@ -3,7 +3,6 @@ from typing import Any, Final, override
from pgvector.sqlalchemy import Vector
from sqlalchemy import (
ARRAY,
Boolean,
Column,
DateTime,
@@ -23,6 +22,7 @@ from sqlalchemy.orm import registry
from template_project.application.access_token.entity import AccessToken
from template_project.application.auth_identity.entity import AuthIdentity, AuthMethod
from template_project.application.common.enums import ExperienceType
from template_project.application.notification_device.entity import NotificationDevice
from template_project.application.resume.entity import Resume, ResumeEmbedding, ResumePrediction
from template_project.application.user.entity import User
@@ -160,6 +160,28 @@ key_skills_table: Final = Table(
Column("id", Integer, autoincrement=True, primary_key=True),
Column("name", String, nullable=False, unique=True)
)
vacancy_table: Final = Table(
"vacancies",
meta_data,
Column("id", UUID, primary_key=True),
Column("deleted_at", DateTime(timezone=True)),
Column("created_at", DateTime(timezone=True), nullable=False),
Column("position", String, nullable=False),
Column("from_salary", Numeric, nullable=False),
Column("to_salary", Numeric, nullable=False),
Column("experience_type", Enum(ExperienceType), nullable=False),
Column("description", nullable=False),
Column("key_skills", nullable=False),
)
vacancy_embedding_table: Final = Table(
"vacancy_embedding",
meta_data,
Column("id", UUID, primary_key=True),
Column("deleted_at", DateTime(timezone=True)),
Column("created_at", DateTime(timezone=True), nullable=False),
Column("vacancy_id", UUID, ForeignKey("vacancies.id", ondelete="CASCADE"), nullable=False),
Column("vector", Vector, nullable=False),
)
mapper_registry.map_imperatively(User, user_table)
@@ -0,0 +1,24 @@
from collections.abc import Sequence
from typing import override
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from template_project.adapters.data_gateways.tables import vacancy_embedding_table, vacancy_table
from template_project.application.vacancy.data_gateway import VacancyDataGateway
from template_project.application.vacancy.entity import Vacancy, VacancyEmbedding
class DefaultVacancyDataGateway(VacancyDataGateway):
def __init__(self, session: AsyncSession) -> None:
self._session = session
@override
async def get_suitable(self, vector: list[float]) -> Sequence[Vacancy]:
statement = (
select(Vacancy)
.join(VacancyEmbedding, vacancy_embedding_table.c.id == vacancy_table.c.id)
.where(vacancy_embedding_table.c.vector.cosine_distance(vector) > 0.5)
)
result = await self._session.execute(statement)
return result.scalars().all()