I am following the Snowflake Python Connector docs for variable binding to avoid SQL injection. I successfully set up a db connection with the following dict of credentials:
import snowflake.connector CONN = snowflake.connector.connect( user=snowflake_creds['user'], password=snowflake_creds['password'], account=snowflake_creds['account'], warehouse=snowflake_creds["warehouse"], database=snowflake_creds['database'], schema=snowflake_creds['schema'], ) cur = CONN.cursor(snowflake.connector.DictCursor) The following block works fine and I get back query results, hard-coding the table name and using the standard format binding:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %s") bind_params = (2) results = cur.execute(command % bind_params).fetchall() Similarly, this block works fine, using the pyformat binding:
command = ("SELECT * FROM TEST_INPUT_TABLE WHERE batch_id = %(id)s") bind_params = {"id": 2} results = cur.execute(command, bind_params).fetchall() But the following two blocks both result in a ProgrammingError (pasted below the second block):
command = ("SELECT * FROM %s WHERE batch_id = %s") bind_params = ("TEST_INPUT_TABLE", 2) results = cur.execute(command, bind_params).fetchall() command = ("SELECT * FROM %(tablename)s WHERE batch_id = %(id)s") bind_params = { "tablename": "TEST_INPUT_TABLE", "id": 2 } results = cur.execute(command, bind_params).fetchall() ProgrammingError: 001011 (42601): SQL compilation error: invalid URL prefix found in: 'TEST_INPUT_TABLE' Is there some difference between how strings and ints get interpolated? I would not think it would make a difference but that is all I can think of. Am I missing something simple here? I don't want to have to choose between hard-coding the table name and putting the system at risk of SQL injection. Thanks for any guidance.