291 lines
9.9 KiB
Python
291 lines
9.9 KiB
Python
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()
|