import pyodbc # ============================== # Conexão com o banco de dados # ============================== DB_CONNECTION_STRING = ( 'DRIVER={ODBC Driver 18 for SQL Server};' 'SERVER=10.77.77.10;' 'DATABASE=GINSENG;' 'UID=supginseng;' 'PWD=Ginseng@;' 'PORT=1433;' 'TrustServerCertificate=yes' ) def refresh_prices(): """Atualiza a tabela price com os dados mais recentes do draft_historico""" print("="*60) print("REFRESH PRICE - Atualização de Preços") print("="*60) conn = pyodbc.connect(DB_CONNECTION_STRING) cursor = conn.cursor() # 1. Buscar dados mais recentes do draft_historico print("\n[1/4] Buscando dados mais recentes do draft_historico...") query_draft = """ SELECT [loja_id] as PDV, [code] as SKU, [pricesellin] as PRICE, [data] FROM [GINSENG].[dbo].[draft_historico] WHERE [data] = ( SELECT MAX([data]) FROM [GINSENG].[dbo].[draft_historico] ) """ cursor.execute(query_draft) draft_data = cursor.fetchall() if not draft_data: print(" ✗ Nenhum dado encontrado no draft_historico") cursor.close() conn.close() return None # Pegar a data mais recente para exibir data_mais_recente = draft_data[0][3] if draft_data else None print(f" ✓ Data mais recente: {data_mais_recente}") print(f" ✓ {len(draft_data)} registros encontrados") # 2. Criar conjunto de chaves PDV+SKU print("\n[2/4] Criando chaves únicas PDV+SKU...") # Criar dicionário com chave PDV+SKU e valor PRICE draft_dict = {} for row in draft_data: pdv = str(row[0]) sku = str(row[1]) price = row[2] key = f"{pdv}_{sku}" draft_dict[key] = {"pdv": pdv, "sku": sku, "price": price} print(f" ✓ {len(draft_dict)} chaves únicas criadas") # 3. Deletar registros existentes na tabela price usando tabela temporária print("\n[3/4] Deletando registros existentes na tabela price...") # Criar tabela temporária print(" Criando tabela temporária...") cursor.execute("IF OBJECT_ID('tempdb..#keys_to_delete') IS NOT NULL DROP TABLE #keys_to_delete") cursor.execute("CREATE TABLE #keys_to_delete (PDV VARCHAR(50), SKU VARCHAR(50))") conn.commit() # Inserir chaves na tabela temporária em batches print(" Inserindo chaves na tabela temporária...") keys_list = [(d['pdv'], d['sku']) for d in draft_dict.values()] batch_size = 1000 for i in range(0, len(keys_list), batch_size): batch = keys_list[i:i + batch_size] placeholders = ",".join(["(?, ?)" for _ in batch]) insert_temp_query = f"INSERT INTO #keys_to_delete (PDV, SKU) VALUES {placeholders}" params = [item for pair in batch for item in pair] cursor.execute(insert_temp_query, params) if (i + batch_size) % 10000 == 0 or (i + batch_size) >= len(keys_list): print(f" → {min(i + batch_size, len(keys_list))}/{len(keys_list)} chaves inseridas na temp...") conn.commit() # Deletar usando JOIN (muito mais rápido) print(" Executando DELETE com JOIN...") delete_query = """ DELETE p FROM [GINSENG].[dbo].[price] p INNER JOIN #keys_to_delete t ON p.[PDV] = t.[PDV] AND p.[SKU] = t.[SKU] """ cursor.execute(delete_query) deleted_count = cursor.rowcount conn.commit() # Limpar tabela temporária cursor.execute("DROP TABLE #keys_to_delete") conn.commit() print(f" ✓ {deleted_count} registros deletados no total") # 4. Inserir novos registros na tabela price (diretamente do draft_historico) print("\n[4/4] Inserindo novos registros na tabela price...") insert_query = """ INSERT INTO [GINSENG].[dbo].[price] ([PDV], [SKU], [PRICE]) SELECT [loja_id], [code], [pricesellin] FROM [GINSENG].[dbo].[draft_historico] WHERE [data] = ( SELECT MAX([data]) FROM [GINSENG].[dbo].[draft_historico] ) """ cursor.execute(insert_query) inserted_count = cursor.rowcount conn.commit() errors = 0 print(f" ✓ {inserted_count} registros inseridos") # ============================================================ # PARTE 2: Processar intra_planejamento_lancamento # ============================================================ print(f"\n{'='*60}") print("PARTE 2: INTRA_PLANEJAMENTO_LANCAMENTO") print(f"{'='*60}") # 5. Buscar dados do intra_planejamento_lancamento print("\n[5/8] Buscando dados do intra_planejamento_lancamento...") query_intra = """ SELECT [PDV], [PRODUTO_LANCAMENTO] as SKU, [PRECO_UND] as PRICE, [DT_ATUALIZACAO] FROM [GINSENG].[dbo].[intra_planejamento_lancamento] """ cursor.execute(query_intra) intra_data = cursor.fetchall() if not intra_data: print(" ✗ Nenhum dado encontrado no intra_planejamento_lancamento") intra_deleted_count = 0 intra_inserted_count = 0 else: print(f" ✓ {len(intra_data)} registros encontrados") # 6. Criar conjunto de chaves PDV+SKU print("\n[6/8] Criando chaves únicas PDV+SKU...") intra_dict = {} for row in intra_data: pdv = str(row[0]) sku = str(row[1]) price = row[2] key = f"{pdv}_{sku}" intra_dict[key] = {"pdv": pdv, "sku": sku, "price": price} print(f" ✓ {len(intra_dict)} chaves únicas criadas") # 7. Deletar registros existentes na tabela price usando tabela temporária print("\n[7/8] Deletando registros existentes na tabela price...") # Criar tabela temporária print(" Criando tabela temporária...") cursor.execute("IF OBJECT_ID('tempdb..#keys_to_delete_intra') IS NOT NULL DROP TABLE #keys_to_delete_intra") cursor.execute("CREATE TABLE #keys_to_delete_intra (PDV VARCHAR(50), SKU VARCHAR(50))") conn.commit() # Inserir chaves na tabela temporária em batches print(" Inserindo chaves na tabela temporária...") intra_keys_list = [(d['pdv'], d['sku']) for d in intra_dict.values()] batch_size = 1000 for i in range(0, len(intra_keys_list), batch_size): batch = intra_keys_list[i:i + batch_size] placeholders = ",".join(["(?, ?)" for _ in batch]) insert_temp_query = f"INSERT INTO #keys_to_delete_intra (PDV, SKU) VALUES {placeholders}" params = [item for pair in batch for item in pair] cursor.execute(insert_temp_query, params) if (i + batch_size) % 10000 == 0 or (i + batch_size) >= len(intra_keys_list): print(f" → {min(i + batch_size, len(intra_keys_list))}/{len(intra_keys_list)} chaves inseridas na temp...") conn.commit() # Deletar usando JOIN print(" Executando DELETE com JOIN...") delete_query_intra = """ DELETE p FROM [GINSENG].[dbo].[price] p INNER JOIN #keys_to_delete_intra t ON p.[PDV] = t.[PDV] AND p.[SKU] = t.[SKU] """ cursor.execute(delete_query_intra) intra_deleted_count = cursor.rowcount conn.commit() # Limpar tabela temporária cursor.execute("DROP TABLE #keys_to_delete_intra") conn.commit() print(f" ✓ {intra_deleted_count} registros deletados no total") # 8. Inserir novos registros na tabela price print("\n[8/8] Inserindo novos registros na tabela price...") insert_query_intra = """ INSERT INTO [GINSENG].[dbo].[price] ([PDV], [SKU], [PRICE]) SELECT [PDV], [PRODUTO_LANCAMENTO], [PRECO_UND] FROM [GINSENG].[dbo].[intra_planejamento_lancamento] """ cursor.execute(insert_query_intra) intra_inserted_count = cursor.rowcount conn.commit() print(f" ✓ {intra_inserted_count} registros inseridos") cursor.close() conn.close() # Resumo final print(f"\n{'='*60}") print("RESUMO FINAL") print(f"{'='*60}") print("\n📦 DRAFT_HISTORICO:") print(f" Data processada: {data_mais_recente}") print(f" Registros no draft: {len(draft_data)}") print(f" Chaves únicas: {len(draft_dict)}") print(f" Deletados do price: {deleted_count}") print(f" Inseridos no price: {inserted_count}") print("\n📦 INTRA_PLANEJAMENTO_LANCAMENTO:") print(f" Registros no intra: {len(intra_data) if intra_data else 0}") print(f" Chaves únicas: {len(intra_dict) if 'intra_dict' in locals() else 0}") print(f" Deletados do price: {intra_deleted_count if 'intra_deleted_count' in locals() else 0}") print(f" Inseridos no price: {intra_inserted_count if 'intra_inserted_count' in locals() else 0}") total_deleted = deleted_count + (intra_deleted_count if 'intra_deleted_count' in locals() else 0) total_inserted = inserted_count + (intra_inserted_count if 'intra_inserted_count' in locals() else 0) print(f"\n📊 TOTAL:") print(f" Total deletados: {total_deleted}") print(f" Total inseridos: {total_inserted}") print(f" Erros: {errors}") print(f"{'='*60}") if errors == 0: print("✓ SUCESSO TOTAL!") else: print("⚠ Concluído com alguns problemas") return { "data": data_mais_recente, "draft_records": len(draft_data), "draft_unique_keys": len(draft_dict), "draft_deleted": deleted_count, "draft_inserted": inserted_count, "intra_records": len(intra_data) if intra_data else 0, "intra_deleted": intra_deleted_count if 'intra_deleted_count' in locals() else 0, "intra_inserted": intra_inserted_count if 'intra_inserted_count' in locals() else 0, "total_deleted": total_deleted, "total_inserted": total_inserted, "errors": errors } # ============================== # EXECUTAR # ============================== if __name__ == "__main__": refresh_prices()