src.offers.postgresql_offers_repository_adapter
PostgreSQL adapter for the offers repository.
1"""PostgreSQL adapter for the offers repository.""" 2 3from typing import override 4 5from psycopg.rows import class_row 6 7from src.lib.postgresql_base import PostgreSQLRepositoryBase 8from .models import Offer 9from .offers_repository_port import OffersRepositoryPort 10 11 12class PostgreSQLOffersRepositoryAdapter(PostgreSQLRepositoryBase, OffersRepositoryPort): 13 """Adapter that stores offers in a PostgreSQL database.""" 14 15 def __init__(self, connection_string: str) -> None: 16 """Initialise with a PostgreSQL connection string. 17 18 Args: 19 connection_string: PostgreSQL connection string. 20 """ 21 PostgreSQLRepositoryBase.__init__(self, connection_string) 22 self._init_db() 23 24 def _init_db(self) -> None: 25 """Initialize the database table for offers.""" 26 self.execute( 27 """ 28 CREATE TABLE IF NOT EXISTS offers ( 29 offer_id TEXT PRIMARY KEY, 30 award_id TEXT NOT NULL 31 ) 32 """ 33 # TODO add indexes for offer_id and award_id 34 ) 35 36 @override 37 def store(self, offer: Offer) -> None: 38 """Persist an offer in PostgreSQL. 39 40 Args: 41 offer: The offer to store. 42 """ 43 self.execute( 44 """ 45 INSERT INTO offers (offer_id, award_id) 46 VALUES (%s, %s) 47 ON CONFLICT (offer_id) DO UPDATE 48 SET award_id = EXCLUDED.award_id 49 """, 50 ( 51 offer.offer_id, 52 offer.award_id, 53 ), 54 ) 55 56 @override 57 def get(self, offer_id: str) -> Offer: 58 """Retrieve an offer by its identifier. 59 60 Args: 61 offer_id: The unique offer identifier. 62 63 Returns: 64 The matching Offer. 65 66 Raises: 67 KeyError: When no offer with the given id exists. 68 """ 69 with self.conn() as conn: 70 row = ( 71 conn.cursor(row_factory=class_row(Offer)) 72 .execute( 73 """ 74 SELECT offer_id, award_id, null AS uri 75 FROM offers 76 WHERE offer_id = %(id)s 77 """, 78 {"id": offer_id}, 79 ) 80 .fetchone() 81 ) 82 83 if row is None: 84 raise KeyError(f"Offer with id {offer_id} not found") 85 86 return row
class
PostgreSQLOffersRepositoryAdapter(src.lib.postgresql_base.PostgreSQLRepositoryBase, src.offers.offers_repository_port.OffersRepositoryPort):
13class PostgreSQLOffersRepositoryAdapter(PostgreSQLRepositoryBase, OffersRepositoryPort): 14 """Adapter that stores offers in a PostgreSQL database.""" 15 16 def __init__(self, connection_string: str) -> None: 17 """Initialise with a PostgreSQL connection string. 18 19 Args: 20 connection_string: PostgreSQL connection string. 21 """ 22 PostgreSQLRepositoryBase.__init__(self, connection_string) 23 self._init_db() 24 25 def _init_db(self) -> None: 26 """Initialize the database table for offers.""" 27 self.execute( 28 """ 29 CREATE TABLE IF NOT EXISTS offers ( 30 offer_id TEXT PRIMARY KEY, 31 award_id TEXT NOT NULL 32 ) 33 """ 34 # TODO add indexes for offer_id and award_id 35 ) 36 37 @override 38 def store(self, offer: Offer) -> None: 39 """Persist an offer in PostgreSQL. 40 41 Args: 42 offer: The offer to store. 43 """ 44 self.execute( 45 """ 46 INSERT INTO offers (offer_id, award_id) 47 VALUES (%s, %s) 48 ON CONFLICT (offer_id) DO UPDATE 49 SET award_id = EXCLUDED.award_id 50 """, 51 ( 52 offer.offer_id, 53 offer.award_id, 54 ), 55 ) 56 57 @override 58 def get(self, offer_id: str) -> Offer: 59 """Retrieve an offer by its identifier. 60 61 Args: 62 offer_id: The unique offer identifier. 63 64 Returns: 65 The matching Offer. 66 67 Raises: 68 KeyError: When no offer with the given id exists. 69 """ 70 with self.conn() as conn: 71 row = ( 72 conn.cursor(row_factory=class_row(Offer)) 73 .execute( 74 """ 75 SELECT offer_id, award_id, null AS uri 76 FROM offers 77 WHERE offer_id = %(id)s 78 """, 79 {"id": offer_id}, 80 ) 81 .fetchone() 82 ) 83 84 if row is None: 85 raise KeyError(f"Offer with id {offer_id} not found") 86 87 return row
Adapter that stores offers in a PostgreSQL database.
PostgreSQLOffersRepositoryAdapter(connection_string: str)
16 def __init__(self, connection_string: str) -> None: 17 """Initialise with a PostgreSQL connection string. 18 19 Args: 20 connection_string: PostgreSQL connection string. 21 """ 22 PostgreSQLRepositoryBase.__init__(self, connection_string) 23 self._init_db()
Initialise with a PostgreSQL connection string.
Args: connection_string: PostgreSQL connection string.
37 @override 38 def store(self, offer: Offer) -> None: 39 """Persist an offer in PostgreSQL. 40 41 Args: 42 offer: The offer to store. 43 """ 44 self.execute( 45 """ 46 INSERT INTO offers (offer_id, award_id) 47 VALUES (%s, %s) 48 ON CONFLICT (offer_id) DO UPDATE 49 SET award_id = EXCLUDED.award_id 50 """, 51 ( 52 offer.offer_id, 53 offer.award_id, 54 ), 55 )
Persist an offer in PostgreSQL.
Args: offer: The offer to store.
57 @override 58 def get(self, offer_id: str) -> Offer: 59 """Retrieve an offer by its identifier. 60 61 Args: 62 offer_id: The unique offer identifier. 63 64 Returns: 65 The matching Offer. 66 67 Raises: 68 KeyError: When no offer with the given id exists. 69 """ 70 with self.conn() as conn: 71 row = ( 72 conn.cursor(row_factory=class_row(Offer)) 73 .execute( 74 """ 75 SELECT offer_id, award_id, null AS uri 76 FROM offers 77 WHERE offer_id = %(id)s 78 """, 79 {"id": offer_id}, 80 ) 81 .fetchone() 82 ) 83 84 if row is None: 85 raise KeyError(f"Offer with id {offer_id} not found") 86 87 return row
Retrieve an offer by its identifier.
Args: offer_id: The unique offer identifier.
Returns: The matching Offer.
Raises: KeyError: When no offer with the given id exists.