from typing import List from sqlalchemy.dialects.postgresql import insert from sqlalchemy.orm import Session from alembic import op import sqlalchemy as sa import os import csv def create_obj(obj_type: type, obj_fields: dict) -> object: """Create object of specific type with specific attribute values. Args: obj_type (type): Class type. obj_fields (dict): Attribute names and values. Returns: object: Created object. """ obj = obj_type() for key, value in obj_fields.items(): setattr(obj, key, value) return obj def map_names_to_obj(obj_type: type, obj_list: list or tuple) -> dict: """Create a set of object and return a mapping of id:object. Args: obj_type (type): Class type. obj_list (list or tuple): Set of attribute values. Returns: dict[int, object]: Dict of created objects by IDs. """ return { fields['id']: create_obj(obj_type, fields) for fields in obj_list } def add_to_session( session: Session, obj_type: type, obj_list: list or tuple) -> dict: """Create objects and add to session. Args: session (Session): SQLAlchemy session object. obj_type (type): Class type. obj_list (list or tuple): Set of attribute values. Returns: dict[int, object]: Dict of created objects by IDs. """ mapping = map_names_to_obj(obj_type, obj_list) session.add_all(mapping.values()) return mapping def path_to_fixture(fixture_name): dirname = os.path.dirname(__file__) return os.path.join(dirname, 'fixtures', fixture_name) def import_data(table_name, fixture_name): bind = op.get_bind() fixture_path = path_to_fixture(fixture_name) f = open(fixture_path, 'r') reader = csv.reader(f) headers = next(reader, None) joined_headers = ", ".join(headers) rows = ["({})".format(",".join(row)) for row in reader] joined_rows = ", ".join(rows) bind.execute('''INSERT INTO "%s" (%s) VALUES %s ON CONFLICT DO NOTHING''' % (table_name, joined_headers, joined_rows)) def import_data_json(table_name: str, json_data: List[dict]): bind = op.get_bind() meta = sa.MetaData(bind=bind) meta.reflect() for item in json_data: insert_table = insert(meta.tables[table_name]).values(**item) op.execute(insert_table.on_conflict_do_nothing()) def import_marketing_accounts(bind, marketing_accounts: List[dict]): meta = sa.MetaData(bind=bind) meta.reflect() marketing_account_table = meta.tables["MarketingAccount"] for account in marketing_accounts: op.execute( marketing_account_table.insert().values( label_id=account["label_id"], provider_id=account["provider_id"], external_id=account["account_id"], type=account["type"], ) ) def drop_marketing_accounts(bind, marketing_accounts_ids: List[str]): meta = sa.MetaData(bind=bind) meta.reflect() marketing_account_table = meta.tables["MarketingAccount"] op.execute( marketing_account_table.delete().where(marketing_account_table.c.external_id.in_(marketing_accounts_ids)) ) def get_table(bind, name): meta = sa.MetaData(bind=bind) meta.reflect() return meta.tables[name]