Estou escrevendo um procedimento armazenado com a API Snowpark do Snowflake, usando Python como linguagem. Quero que meu procedimento registre toda vez que executar uma instrução DML. Quando escrevo procedimentos que constroem as strings SQL e depois as executo via session.call(SQLString)
, isso é fácil - posso registrar a string SQL que construí. Essa abordagem se parece com isso em um procedimento JavaScript:
const EXAMPLE_QUERY = `CALL EXAMPLE_PROCEDURE('${ARG1}', '${ARG2}', '${ARG3}');`;
let exampleStatement = snowflake.createStatement({sqlText: EXAMPLE_QUERY});
log(EXAMPLE_QUERY, "info", `Exit code: ${exitCode}`);
O EXAMPLE_QUERY
é em si uma string que eu posso registrar diretamente, e ele me diz exatamente qual declaração DML é executada quando eu leio os registros. Muito informativo e conveniente.
No momento, estou tentando usar o session
objeto e os métodos Snowpark, então não tenho uma string SQL que construo no procedimento. O que posso obter do meu session
objeto para colocar na minha tabela de log? Não precisa ser exatamente uma instrução SQL, mas gostaria de saber o que está acontecendo com os dados. A última linha do procedimento de exemplo abaixo é o problema que estou tentando resolver.
CREATE OR REPLACE PROCEDURE EXAMPLE()
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'run'
AS
$$
def run(session):
PROCEDURE_NAME = 'EXAMPLE'
def log(execution, level, message):
try:
logging_function = 'EXAMPLE_DB.EXAMPLE_SCHEMA.LOGGING' # This UDF already lives in the database
session.call(logging_function, PROCEDURE_NAME, execution, level, message)
except Exception as e:
return {"status": "ERROR", "message": "Error in the logging function: "+str(e)}
try:
log(f'CALL {PROCEDURE_NAME}({ADMIN_DB}, {BUILD_DB}, {BUILD_SCHEMA}, {BUILDS_TO_KEEP})', 'info', 'Begin run')
example_table = "EXAMPLE_DB.EXAMPLE_SCHEMA.EXAMPLE_TABLE"
get_tables_query = session.table(example_table).select('EXAMPLE_COLUMN').distinct()
example_output = [row['EXAMPLE_COLUMN'] for row in get_tables_query.collect()]
log(get_tables_query, 'info', 'Unique tables returned: '+str(len(target_tables))) # Does not work!
Você pode usar o Histórico de consultas como um gerenciador de contexto para registrar consultas
Da documentação
E então você pode usar QueryRecord para obter detalhes como sql_text, query_id etc.
Com as informações acima, você pode coletar as declarações DML como abaixo
Simplifiquei seu procedimento para fins de demonstração
Isso retorna