Ejemplo n.º 1
0
    async def update(self,
                     con: Connection = None,
                     table: str = '',
                     where_dict: dict = None,
                     **update_params: dict) -> list:

        values = ','.join(
            ["{}='{}'".format(k, v) for k, v in update_params.items()])

        where = ''
        if where_dict is not None:
            where = ' where '
            where += ' and '.join([
                self.WHERE.format(key=k, value=v)
                for k, v in where_dict.items()
            ])
        query = self.UPDATE.format(table=table, values=values, where=where)

        if not con:
            pool = await self.get_pool()
            async with pool.acquire() as con:
                async with con.transaction():
                    results = await con.fetch(query)
        else:
            async with con.transaction():
                results = await con.fetch(query)

        return results
Ejemplo n.º 2
0
async def create_staging_table(conn: Connection):
    """Create a staging table for the cards, empties it if it exists.

    Note that the table is unlogged, so it's supposed to be used for this
    operation only, then lost.
    """
    async with conn.transaction():
        await conn.execute("DROP TABLE IF EXISTS card_stg")
    async with conn.transaction():
        await conn.execute("""
        CREATE UNLOGGED TABLE card_stg (
            from_lang    SMALLINT NOT NULL,
            to_lang      SMALLINT NOT NULL,
            from_id      INTEGER  NOT NULL,
            to_id        INTEGER  NOT NULL,
            from_txt     TEXT     NOT NULL,
            original_txt TEXT     NOT NULL,
            to_tokens    TEXT[]   NOT NULL
        ) PARTITION BY HASH (from_id, to_id);
        """)
        for i in range(10):
            await conn.execute(f"""
        CREATE UNLOGGED TABLE card_stg_h{i}
            PARTITION OF card_stg
                FOR VALUES WITH (MODULUS 10, REMAINDER {i});
        """)
Ejemplo n.º 3
0
 async def execute(self, con: Connection = None, query: str = ''):
     if not con:
         pool = await self.get_pool()
         async with pool.acquire() as con:
             async with con.transaction():
                 await con.execute(query)
     else:
         async with con.transaction():
             await con.execute(query)
Ejemplo n.º 4
0
async def insertTop10Companies(connection: Connection):
    async with connection.transaction():
        await connection.execute('''
            DELETE FROM empresas
            ''')

        await connection.copy_records_to_table(
            "empresas",
            records=[(1, "Oi", "OIBR-C", "Rio de Janeiro, Rio de Janeiro",
                      "Telecomunicações", 10),
                     (2, "Braskem", "BRKM5.SAO", "São Paulo, São Paulo",
                      "Petroquímica", 9),
                     (3, "Itaúsa", "ITSA4.SAO", "Brasil",
                      "Finanças e indústria", 8),
                     (4, "JBS", "JBSS3.SAO", "São Paulo, São Paulo",
                      "Alimentício", 7),
                     (5, "Eletrobras", "ELET6.SAO",
                      "Rio de Janeiro, Rio de Janeiro", "Energia elétrica", 6),
                     (6, "Banco do Brasil", "BBAS3.SAO",
                      "Brasília, Distrito Federal", "Bancário", 5),
                     (7, "Vale", "VALE3.SAO", "Rio de Janeiro, Rio de Janeiro",
                      "Mineração", 4),
                     (8, "Banco Bradesco", "BBDC4.SAO", "Osasco, São Paulo",
                      "Bancário", 3),
                     (9, "Itaú Unibanco", "ITUB4.SAO", "São Paulo, São Paulo",
                      "Bancário", 2),
                     (10, "Petrobras", "PETR4.SAO",
                      "Rio de Janeiro, Rio de Janeiro", "Petróleo e gás", 1)])
Ejemplo n.º 5
0
async def db_import_rule(rule_id: str,
                         rule_cves: list,
                         conn: Connection,
                         rule_only=False):
    """Import single error key into database"""
    try:
        async with conn.transaction():
            inserted = await conn.fetchrow(
                """INSERT INTO insights_rule (name, rule_only)
                                                VALUES($1, $2)
                                                ON CONFLICT (name) DO UPDATE
                                                SET name = EXCLUDED.name, rule_only = EXCLUDED.rule_only
                                                RETURNING id AS inserted""",
                rule_id, rule_only)
            RULES_CACHE[rule_id] = inserted[0]
            to_insert = []
            for rule_cve in rule_cves:
                if rule_cve not in CVES_CACHE:
                    await db_import_cve(rule_cve, conn)
                to_insert.append((inserted[0], CVES_CACHE[rule_cve]))
            await conn.executemany(
                """INSERT INTO cve_rule_mapping (rule_id, cve_id)
                                        VALUES ($1, $2) ON CONFLICT DO NOTHING""",
                to_insert)
    # pylint: disable=broad-except
    except Exception:
        DATABASE_ERROR.inc()
        LOGGER.exception("Error during inserting rule: ")
Ejemplo n.º 6
0
async def merge_tables(conn: Connection, p_id: int):
    """Merge the staging table and the final one."""
    async with conn.transaction():
        logger.debug('Detecting cards no longer valid...')
        res = await conn.fetchrow(f"""
            SELECT count(1) AS to_delete
            FROM card_h{p_id} c
                LEFT JOIN card_stg_h{p_id} s
                USING (from_id, to_id)
            WHERE s.from_id IS NULL
            """)
        if res['to_delete'] > 500:
            # around 10 cards are deleted per day, too many may be an issue with the
            # file, so better stop rather than deleting everything
            raise ValueError(f"Suspect number of cards to delete: {res['to_delete']}")
        if res['to_delete'] > 0:
            logger.info(f"Found {res['to_delete']} invalid cards, deleting them")
            await conn.execute(f"""
                DELETE
                FROM card_h{p_id}
                WHERE
                    (from_lang, to_lang) IN
                    (
                        SELECT
                            c.from_lang,
                            c.to_lang
                        FROM card_h{p_id} c
                            LEFT JOIN card_stg_h{p_id} s
                                USING (from_id, to_id)
                        WHERE
                            s.from_id IS NULL)
                """)
        else:
            logger.info('There were no cards to delete')
        logger.info('Updating the cards which changed...')
        res = await conn.fetchrow(f"""
                UPDATE card_h{p_id} c
                SET
                    from_txt     = s.from_txt,
                    original_txt = s.original_txt,
                    to_tokens    = s.to_tokens
                FROM card_stg_h{p_id} s
                WHERE
                    c.from_id = s.from_id
                AND c.to_id = s.to_id
                AND (c.from_txt, c.to_tokens) <> (s.from_txt, s.to_tokens)
            """)
        logger.info(f'Update successful: changes {res}')
        logger.info('Inserting new cards...')
        res = await conn.fetchrow(f"""
        INSERT INTO card_h{p_id}
            SELECT
                s.*
            FROM
                card_stg_h{p_id} s
                LEFT JOIN card_h{p_id} c
                    USING(from_id, to_id)
            WHERE
                c.from_lang IS NULL
        """)
Ejemplo n.º 7
0
    async def delete(self,
                     con: Connection = None,
                     table: str = '',
                     where_dict: dict = None):
        where = ' where '
        where += ' and '.join(
            [self.WHERE.format(key=k, value=v) for k, v in where_dict.items()])
        query = self.DELETE.format(table=table, where=where)

        if not con:
            pool = await self.get_pool()
            async with pool.acquire() as con:
                async with con.transaction():
                    await con.execute(query)
        else:
            async with con.transaction():
                await con.execute(query)
Ejemplo n.º 8
0
async def createCompanyTable(connection: Connection):
    async with connection.transaction():
        await connection.execute('''
            CREATE TABLE IF NOT EXISTS empresas(
                id bigserial NOT NULL,
                nome character varying(50) NOT NULL,
                simbolo_empresa character varying(20) PRIMARY KEY NOT NULL UNIQUE,
                regiao character varying(50),
                setor character varying(20),
                rank int
            )''')
Ejemplo n.º 9
0
async def createStockTable(connection: Connection):
    async with connection.transaction():
        await connection.execute('''
            CREATE TABLE IF NOT EXISTS cotacoes(
                preco float(3),
                volume bigint,
                data timestamp without time zone,
                variacao float(3),
                variacao_por_cento float(5),
                simbolo_empresa character varying(20) NOT NULL,
                CONSTRAINT cotacao_fk FOREIGN KEY(simbolo_empresa) REFERENCES empresas(simbolo_empresa) ON DELETE CASCADE
            )''')
Ejemplo n.º 10
0
    async def insert(self,
                     con: Connection = None,
                     table: str = '',
                     value_dict: dict = None):

        columns = ",".join(value_dict.keys())
        placeholder = ",".join(
            ['${}'.format(i) for i in range(1,
                                            len(value_dict) + 1)])

        query = self.INSERT.format(table=table,
                                   columns=columns,
                                   values=placeholder)

        if not con:
            pool = await self.get_pool()
            async with pool.acquire() as con:
                async with con.transaction():
                    result = await con.fetchrow(query, *value_dict.values())
        else:
            async with con.transaction():
                result = await con.fetchrow(query, *value_dict.values())

        return result
Ejemplo n.º 11
0
async def ingest_cards_file(
        conn: Connection, jsonl_file: str, languages_ids: Dict[str, int]):
    """Insert a cards file in the staging table card_stg."""
    pending = []
    last_update = time()
    for idx, line in enumerate(open(jsonl_file)):
        card = json.loads(line)
        try:
            pending.append((
                languages_ids[card['from_lang']],
                languages_ids[card['to_lang']],
                card['from_id'],
                card['to_id'],
                card['from_txt'],
                card['original_txt'],
                card['resulting_tokens'],
            ))
        except KeyError as ke:
            # missing language or weird line
            logger.warning(f'Error processing a row: {line}: {ke}')
        if len(pending) > 2000:
            async with conn.transaction():
                await conn.copy_records_to_table(
                    'card_stg',
                    records=pending,
                )
            pending = []
            if time() > last_update + 60:
                logger.debug(f'Ingested {idx} so far...')
                last_update = time()
    logger.debug('Almost done, writing the remaining entries...')
    async with conn.transaction():
        await conn.copy_records_to_table(
            'card_stg',
            records=pending,
        )
Ejemplo n.º 12
0
async def _execute_file(migration_file: MigrationFile, conn: Connection):
    log.info(f"EXECUTE {migration_file.stamp} {migration_file.name}")

    try:
        async with conn.transaction():
            with open(migration_file.path) as stream:
                migration_sql = stream.read()
                await conn.execute(migration_sql)

        insert_sql = "INSERT INTO arctic_tern_migrations VALUES ($1, $2, $3, now())"
        await conn.execute(insert_sql, migration_file.stamp,
                           migration_file.name, migration_file.hash_)
    except PostgresError as e:
        log.error(e)
        raise e
Ejemplo n.º 13
0
async def db_import_cve(cve: str, conn: Connection):
    """Import missing CVE metadata into database"""
    # Attempt to get CVE data from VMAAS
    LOGGER.info("Attempting to get %s data from VMAAS", cve)
    cve_request_endpoint = format_vmaas_cve_endpoint(cve)

    cve_page = await vmaas_request(cve_request_endpoint, method="GET")
    success = True

    try:
        cve_data = cve_page["cve_list"][cve]
    except (KeyError, TypeError):
        LOGGER.error("Error importing %s from VMAAS", cve)
        success = False
    try:
        async with conn.transaction():
            if success:
                impact_id_map = {}
                async for row in conn.cursor(
                        "SELECT name, id FROM cve_impact"):
                    impact_name, impact_id = row
                    impact_id_map[impact_name] = impact_id

                cve_row = construct_cve_row(cve_data,
                                            impact_id_map,
                                            asyncpg_type=True)
                inserted = await conn.fetchrow(
                    """INSERT INTO cve_metadata
                                       (cve, description, impact_id, public_date, modified_date,
                                       cvss3_score, cvss3_metrics, cvss2_score, cvss2_metrics, redhat_url,
                                       secondary_url, advisories_list)
                                       VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
                                       ON CONFLICT (cve) DO UPDATE
                                       SET
                                         description = EXCLUDED.description,
                                         impact_id = EXCLUDED.impact_id,
                                         public_date = EXCLUDED.public_date,
                                         modified_date = EXCLUDED.modified_date,
                                         cvss3_score = EXCLUDED.cvss3_score,
                                         cvss3_metrics = EXCLUDED.cvss3_metrics,
                                         cvss2_score = EXCLUDED.cvss2_score,
                                         cvss2_metrics = EXCLUDED.cvss2_metrics,
                                         redhat_url = EXCLUDED.redhat_url,
                                         secondary_url = EXCLUDED.secondary_url,
                                         advisories_list = EXCLUDED.advisories_list
                                       RETURNING id AS inserted""", *cve_row)

            # if vmaas was not available insert empty cve
            else:
                inserted = await conn.fetchrow(
                    """INSERT INTO cve_metadata (cve, description, impact_id)
                                                    VALUES ($1, $2, $3)
                                                    ON CONFLICT (cve) DO UPDATE
                                                    SET cve = $1
                                                    RETURNING id AS inserted""",
                    cve, 'unknown', 0)
            CVES_CACHE[cve] = inserted[0]
    # pylint: disable=broad-except
    except Exception:
        DATABASE_ERROR.inc()
        LOGGER.exception("Error during inserting CVE: ")
Ejemplo n.º 14
0
async def store_language_codes(conn: Connection) -> Dict[str, int]:
    """Update the language codes and return the code -> id dictionary.

    The DB is updated if the name changed or a language is new.

    If a language is in the DB but not in the hardcoded list, an exception is raised.

    Returns
    -------
    Dict[str, int]
        A dictionary mapping the ISO code of a language with its ID

    Raises
    ------
    ValueError
        In case a language was in the DB but not in the hardcoded list
    """
    languages_ids = {}  # ISO -> (id, name)
    max_id = 0
    async with conn.transaction():
        res = await conn.fetch('SELECT id, name, iso693_3 FROM language')
        for lng in res:
            languages_ids[lng['iso693_3']] = (lng['id'], lng['name'])
            if max_id < lng['id']:
                max_id = lng['id']
    for iso, name in ISO_693_3.items():
        if iso in languages_ids:
            pre_name = languages_ids[iso][1]
            # different name? update it
            if pre_name != name:
                logger.info(
                    f'Language with ISO {iso} is now named {name} instead of {pre_name}'
                    )
                await conn.execute(
                    """UPDATE language
                        SET name = $1
                        WHERE iso693_3 = $2
                    """,
                    name,
                    iso,
                )
        else:
            # not there, insert it
            max_id += 1
            logger.info(f'New language, {iso} => {name} will have id {max_id}')
            languages_ids[iso] = (max_id, name)
            await conn.execute(
                """INSERT INTO language(
                    id,
                    iso693_3,
                    name)
                    VALUES ($1, $2, $3)""",
                max_id, iso, name
                )
    # now all of ISO_693_3 elements are in the DB and in language_ids
    # let's check for language_ids which are gone

    gone_languages = set(languages_ids.keys()).difference(ISO_693_3.keys())
    if len(gone_languages) > 0:
        raise ValueError(
            f'Some languages are in the DB but are unknow! They are {gone_languages}'
        )

    return {iso: id_ for iso, (id_, _) in languages_ids.items()}
Ejemplo n.º 15
0
async def delete_staging_table(conn: Connection):
    """Delete the staging table."""
    async with conn.transaction():
        await conn.execute("DROP TABLE card_stg")