1- from sqlalchemy import select
1+ import math
2+ from operator import and_
3+ from typing import Literal , Sequence
4+
5+ from sqlalchemy import func , select
26
37from app .core .database import database
4- from app .models .jmy import JmyCompany
8+ from app .models .jmy import JmyCompany , JmyTimeSeries
59from app .repositories .base import BaseRepository
610
711
@@ -18,3 +22,65 @@ async def read_by_name(self, name: str, eager: bool = False) -> JmyCompany | Non
1822 result = await session .execute (stmt )
1923 entity = result .scalar_one_or_none ()
2024 return entity
25+
26+ async def read_page (
27+ self ,
28+ page : int ,
29+ size : int ,
30+ sort_by : Literal ["old" , "new" ],
31+ filter_by : Literal ["ms" , "phd" , "all" ],
32+ ) -> tuple [Sequence [JmyCompany ], int ]:
33+ jmy_ms = [
34+ "벤처기업부설연구소" ,
35+ "중견기업부설연구소" ,
36+ "중소기업부설연구소" ,
37+ ]
38+ latest_date_subq = (
39+ select (
40+ JmyTimeSeries .company_id , func .max (JmyTimeSeries .date ).label ("max_date" )
41+ )
42+ .group_by (JmyTimeSeries .company_id )
43+ .subquery ()
44+ )
45+ total_expr = (
46+ (JmyTimeSeries .b_old + JmyTimeSeries .a_old )
47+ if sort_by == "old"
48+ else (JmyTimeSeries .b_new + JmyTimeSeries .a_new )
49+ )
50+ total_subq = (
51+ select (
52+ JmyTimeSeries .company_id ,
53+ total_expr .label ("total" ),
54+ )
55+ .join (
56+ latest_date_subq ,
57+ and_ (
58+ JmyTimeSeries .company_id == latest_date_subq .c .company_id ,
59+ JmyTimeSeries .date == latest_date_subq .c .max_date ,
60+ ),
61+ )
62+ .subquery ()
63+ )
64+ stmt = select (self .model ).outerjoin (
65+ total_subq , self .model .id == total_subq .c .company_id
66+ )
67+ if filter_by == "ms" :
68+ stmt = stmt .where (self .model .type_ .in_ (jmy_ms ))
69+ elif filter_by == "phd" :
70+ stmt = stmt .where (self .model .type_ .notin_ (jmy_ms ))
71+ offset = (page - 1 ) * size
72+ stmt = stmt .order_by (total_subq .c .total .desc ()).offset (offset ).limit (size )
73+ session = database .scoped_session ()
74+ results = await session .execute (stmt )
75+ entities = results .scalars ().all ()
76+ _stmt = select (func .count (self .model .id )).outerjoin (
77+ total_subq , self .model .id == total_subq .c .company_id
78+ )
79+ if filter_by == "ms" :
80+ _stmt = _stmt .where (self .model .type_ .in_ (jmy_ms ))
81+ elif filter_by == "phd" :
82+ _stmt = _stmt .where (self .model .type_ .notin_ (jmy_ms ))
83+ result = await session .execute (_stmt )
84+ total_count = result .scalar_one ()
85+ total_pages = math .ceil (total_count / size )
86+ return entities , total_pages
0 commit comments