def execute(self, context):
     self.log.info('Executing: %s', self.sql)
     hook = MsSqlHook(mssql_conn_id=self.mssql_conn_id,
                      schema=self.database)
     hook.run(self.sql,
              autocommit=self.autocommit,
              parameters=self.parameters)
Beispiel #2
0
def execute_from_file(connection_name, query):
    try:
        logging.info('Executing: ' + str(query))
        hook = MsSqlHook(mssql_conn_id=connection_name)
        hook.run(str(query))
    except Exception as e:
        raise AirflowException(e)
 def execute(self, context):
     _log.info('Executing: ' + str(self.sql))
     hook = MsSqlHook(mssql_conn_id=self.mssql_conn_id)
     hook.run(self.sql,
              autocommit=self.autocommit,
              parameters=self.parameters)
Beispiel #4
0
 def execute(self, context):
     logging.info('Executing: ' + str(self.sql))
     hook = MsSqlHook(mssql_conn_id=self.mssql_conn_id)
     hook.run(self.sql, parameters=self.parameters)
 def execute(self, context):
     self.log.info('Executing: %s', self.sql)
     hook = MsSqlHook(mssql_conn_id=self.mssql_conn_id,
                      schema=self.database)
     hook.run(self.sql, autocommit=self.autocommit,
              parameters=self.parameters)
 def execute(self, context):
     _log.info('Executing: ' + str(self.sql))
     hook = MsSqlHook(mssql_conn_id=self.mssql_conn_id)
     hook.run(self.sql, autocommit=self.autocommit, parameters=self.parameters)
Beispiel #7
0
def sync_db_2_db(source_conn_id: str,
                 destination_conn_id: str,
                 table: str,
                 date_column: str,
                 key_column: str,
                 source_schema: str,
                 destination_schema: str,
                 increment_schema: str,
                 sync_exclusions: bool = False,
                 source_exc_schema: str = None,
                 source_exc_table: str = None,
                 source_exc_column: str = None,
                 chunksize: int = 1000) -> None:
    """ Realiza a atualização incremental de uma tabela. A sincronização
    é realizada em 3 etapas. 1-Envia s alterações necessárias para uma
    tabela intermediária localizada no esquema `increment_schema`.
    2-Realiza os Updates. 3-Realiza os Insertes. Apenas as colunas que
    existam na tabela no BD destino serão sincronizadas. Funciona com
    Postgres na origem e MsSql no destino. O algoritmo também realiza
    sincronização de exclusões.

    Exemplo:
        sync_db_2_db(source_conn_id=SOURCE_CONN_ID,
                     destination_conn_id=DEST_CONN_ID,
                     table=table,
                     date_column=date_column,
                     key_column=key_column,
                     source_schema=SOURCE_SCHEMA,
                     destination_schema=STG_SCHEMA,
                     chunksize=CHUNK_SIZE)

    Args:
        source_conn_id (str): string de conexão airflow do DB origem
        destination_conn_id (str): string de conexão airflow do DB destino
        table (str): tabela a ser sincronizada
        date_column (str): nome da coluna a ser utilizado para
        identificação dos registros atualizados na origem.
        key_column (str): nome da coluna a ser utilizado como chave na
        etapa de atualização dos registros antigos que sofreram
        atualizações na origem.
        source_eschema (str): esquema do BD na origem
        destination_schema (str): esquema do BD no destino
        increment_schema (str): Esquema no banco utilizado para tabelas
        temporárias. Caso esta variável seja None, esta tabela será
        criada no mesmo schema com sufixo '_alteracoes'
        sync_exclusions (bool): opção de sincronizar exclusões.
        Default = False.
        source_exc_schema (str): esquema da tabela na origem onde estão
        registradas exclusões
        source_exc_table (str): tabela na origem onde estão registradas
        exclusões
        source_exc_column (str): coluna na tabela na origem onde estão
        registradas exclusões
        chunksize (int): tamanho do bloco de leitura na origem.
        Default = 1000 linhas

    Return:
        None

    Todo:
        * Automatizar a criação da tabela gêmea e remoção ao final
        * Transformar em Airflow Operator
        * Possibilitar ler de MsSql e escrever em Postgres
        * Possibilitar inserir data da carga na tabela de destino
        * Criar testes
    """
    source_table_name = f"{source_schema}.{table}"
    dest_table_name = f"{destination_schema}.{table}"
    if increment_schema:
        inc_table_name = f"{increment_schema}.{table}"
    else:
        inc_table_name = f"{destination_schema}.{table}_alteracoes"

    source_hook = PostgresHook(postgres_conn_id=source_conn_id,
                               autocommit=True)
    dest_hook = MsSqlHook(mssql_conn_id=destination_conn_id, autocommit=True)
    col_list = get_table_cols_name(destination_conn_id, destination_schema,
                                   table)

    dest_rows_count = _table_rows_count(dest_hook, dest_table_name)
    print(f"Total de linhas atualmente na tabela destino: {dest_rows_count}.")
    # If de tabela vazia separado para evitar erro na _build_filter_condition()
    if dest_rows_count == 0:
        raise Exception("Tabela destino vazia! Utilize carga full!")

    ref_value, where_condition = _build_filter_condition(
        dest_hook, dest_table_name, date_column, key_column)
    new_rows_count = _table_rows_count(source_hook, source_table_name,
                                       where_condition)
    print(f"Total de linhas novas ou modificadas: {new_rows_count}.")

    worth_increment = (new_rows_count / dest_rows_count) < 0.3
    if not worth_increment:
        raise Exception("Muitas linhas a inserir! Utilize carga full!")

    # Guarda as alterações e inclusões necessárias
    select_sql = build_select_sql(f"{source_table_name}", col_list)
    select_diff = f"{select_sql} WHERE {where_condition}"
    print(f"SELECT para espelhamento: {select_diff}")
    copy_db_to_db(destination_table=f"{inc_table_name}",
                  source_conn_id=source_conn_id,
                  source_provider='PG',
                  destination_conn_id=destination_conn_id,
                  destination_provider='MSSQL',
                  source_table=None,
                  select_sql=select_diff,
                  destination_truncate=True,
                  chunksize=chunksize)

    # Reconstrói índices
    sql = f"ALTER INDEX ALL ON {inc_table_name} REBUILD"
    dest_hook.run(sql)

    print(f"Iniciando carga incremental na tabela {dest_table_name}.")
    updates_sql, inserts_sql = _build_incremental_sqls(
        dest_table=f"{dest_table_name}",
        source_table=f"{inc_table_name}",
        key_column=key_column,
        column_list=col_list)
    # Realiza updates
    dest_hook.run(updates_sql)
    # Realiza inserts de novas linhas
    dest_hook.run(inserts_sql)

    # Se precisar aplicar as exclusões da origem no destino:
    if sync_exclusions:
        source_exc_sql = f"""SELECT {key_column}
                             FROM {source_exc_schema}.{source_exc_table}
                             WHERE {source_exc_column} > '{ref_value}'
                          """
        rows = source_hook.get_records(source_exc_sql)
        ids_to_del = [row[0] for row in rows]
        if ids_to_del:
            ids = ", ".join(str(id) for id in ids_to_del)
            sql = f"""
                DELETE FROM {dest_table_name}
                WHERE {key_column} IN ({ids})
            """
            dest_hook.run(sql)
        print("Quantidade de linhas possivelmente excluídas:", len(ids_to_del))