Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/prepare data #200

Merged
merged 13 commits into from
Apr 24, 2024
26 changes: 21 additions & 5 deletions src/api/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# third-party
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy import inspect

# local
import src.db.models as models
Expand All @@ -27,6 +28,7 @@ class SqlAlchemyBaseRepository(AbstractRepository):
def __init__(self, session, model_class):
self.session = session
self.model_class = model_class
self.primary_keys = [key.name for key in inspect(self.model_class).primary_key]

def add(self, entity):
self.session.add(entity)
Expand All @@ -46,10 +48,16 @@ def add_or_update(self, entity):

def add_or_update_list(self, entities: List[Dict[str, Any]]):
stmt = insert(self.model_class).values(entities)
stmt = stmt.on_conflict_do_update(
index_elements=["id"],
set_={col.name: col for col in stmt.excluded if not col.primary_key},
)
update_dict = {col.name: col for col in stmt.excluded if not col.primary_key}

if update_dict:
stmt = stmt.on_conflict_do_update(
index_elements=self.primary_keys,
set_=update_dict,
)
else:
stmt = stmt.on_conflict_do_nothing(index_elements=self.primary_keys)

self.session.execute(stmt)
self.session.commit()

Expand Down Expand Up @@ -130,14 +138,19 @@ def __init__(self, session):

class SqlAlchemyCommitteeHasTopicRepository(SqlAlchemyBaseRepository):
def __init__(self, session):
super().__init__(session, models.Committee)
super().__init__(session, models.CommitteeHasTopic)


class SqlAlchemyPollRepository(SqlAlchemyBaseRepository):
def __init__(self, session):
super().__init__(session, models.Poll)


class SqlAlchemyVoteRepository(SqlAlchemyBaseRepository):
def __init__(self, session):
super().__init__(session, models.Vote)


class SqlAlchemyFactory:
"""Factory class to create repositories"""

Expand Down Expand Up @@ -180,3 +193,6 @@ def create_poll_repository(
self,
) -> SqlAlchemyPollRepository:
return SqlAlchemyPollRepository(self.session)

def create_vote_repository(self) -> SqlAlchemyVoteRepository:
return SqlAlchemyVoteRepository(self.session)
35 changes: 24 additions & 11 deletions src/service_layer/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@


ENTITY_HANDLERS = {
Entity.PARTY.value: utils.prepare_party_data,
Entity.PARLIAMENT.value: utils.prepare_parliament_data,
Entity.PARLIAMENT_PERIOD.value: utils.prepare_parliament_period_data,
Entity.TOPIC.value: utils.prepare_topic_data,
Entity.COMMITTEE.value: utils.prepare_committee_data,
Entity.POLL.value: utils.prepare_poll_data,
Entity.PARTY.value: [utils.prepare_party_style_data, utils.prepare_party_data],
Entity.PARLIAMENT.value: [utils.prepare_parliament_data],
Entity.PARLIAMENT_PERIOD.value: [utils.prepare_parliament_period_data],
Entity.TOPIC.value: [utils.prepare_topic_data],
Entity.COMMITTEE.value: [
utils.prepare_committee_data,
utils.prepare_committee_has_topic_data,
],
Entity.POLL.value: [utils.prepare_poll_data],
}

DATA_HANDLERS = {
Expand Down Expand Up @@ -55,22 +58,32 @@ def prepare_update_data(command: commands.PrepareUpdateData):
data = command.data

if entity in ENTITY_HANDLERS:
entity_data = ENTITY_HANDLERS[entity](data)
return {"entities": DATA_HANDLERS[entity], "data": [entity_data]}
entity_data = []
for prepare_data_func in ENTITY_HANDLERS[entity]:
if prepare_data_func and len(data) != 0:
entity_data.append(prepare_data_func(data))
return {"entities": DATA_HANDLERS[entity], "data": entity_data}
else:
return {"entities": [], "data": []}


# Step 3
def update_table(command: commands.UpdateTable):
factory = repository.SqlAlchemyFactory(command.session)

if len(command.entities) != len(command.data):
logger.error(
"Number of entities and data does not match. Entities: %s, Data: %s",
len(command.entities),
len(command.data),
)
return
for entity, data in zip(command.entities, command.data):
repo = utils.get_repository(factory, entity)
if repo is not None:

if repo is not None and len(data) != 0:
repo.add_or_update_list(data)
else:
logger.error(f"Repository for entity {entity} not found.")
logger.error(f"Repository for {entity} not found.")


def publish_missing_entity_fetched_event(
Expand Down
31 changes: 21 additions & 10 deletions src/service_layer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,17 @@ def fetch_missing_entities(self) -> List[models.Party]:
return data_list


def get_repository(factory: SqlAlchemyFactory, entity: str):
def get_repository(
factory: SqlAlchemyFactory, entity: str
) -> SqlAlchemyBaseRepository | None:
entity_factory_map = {
Entity.PARTY.value: factory.create_party_repository,
Entity.PARTY_STYLE.value: factory.create_party_style_repository,
Entity.PARLIAMENT.value: factory.create_parliament_repository,
Entity.PARLIAMENT_PERIOD.value: factory.create_parliament_period_repository,
Entity.TOPIC.value: factory.create_topic_repository,
Entity.COMMITTEE.value: factory.create_committee_repository,
Entity.COMMITTEE_HAS_TOPIC.value: factory.create_committee_has_topic_repository,
Entity.POLL.value: factory.create_poll_repository,
}
if entity in entity_factory_map:
Expand All @@ -113,7 +117,7 @@ def get_repository(factory: SqlAlchemyFactory, entity: str):
return None


def prepare_party_data(api_parties):
def prepare_party_style_data(api_parties):
party_styles = [
{
"id": ap.get("id"),
Expand All @@ -124,6 +128,11 @@ def prepare_party_data(api_parties):
}
for ap in api_parties
]

return party_styles


def prepare_party_data(api_parties):
parties = [
{
"id": ap["id"],
Expand All @@ -136,7 +145,7 @@ def prepare_party_data(api_parties):
}
for ap in api_parties
]
return party_styles, parties
return parties


def prepare_parliament_data(api_parliaments):
Expand Down Expand Up @@ -205,19 +214,21 @@ def prepare_committee_data(api_committees):
}
for api_committee in api_committees
]

return committees


def prepare_committee_has_topic_data(api_committees):
committee_topics = []
for api_committee in api_committees:
for topic in api_committee["field_topics"]:
committee_topics.append(
{
"committee_id": api_committee["id"],
"topic_id": topic["id"],
}
)
if api_committee["field_topics"] is not None:
for topic in api_committee["field_topics"]:
committee_topics.append(
{
"committee_id": api_committee["id"],
"topic_id": topic["id"],
}
)
return committee_topics


Expand Down
Loading