2

I cannot find out, how to use pandas.read_sql_query and correctly (= safely against sql injection) parametrize table names (or other sql identifiers). Using sqlalchemy+psycopg2 to access PostgreSQL database.

Example of what doesn't work:

import os
import pandas
from sqlalchemy import create_engine
db = create_engine(os.getenv(POSTGRES_CONNSTRING))
pandas.read_sql_query(sql='select * from %(schema)s.%(table)s',
                      con = db,
                      params={'schema': 'public', 'table': 'table_name'})

Yields:

SyntaxError: syntax error at or near "'public'"
LINE 1: select * from 'public'.'table_name'

For psycopg2 the correct solution is described here.

import psycopg2
query = psycopg2.sql.SQL('select * from {schema}.{table}') \
                        .format(schema = psycopg2.sql.Identifier('public'),
                                table = psycopg2.sql.Identifier('table_name'))

But the query is now of type psycopg2.sql.Composed, which I can pass to the execute methods in psycopg2 but not to pandas.read_sql_query.

Is there any good solution to this?

1
  • There is no way to parametrize table or schema names. You can only parametrize the values of columns Commented May 19, 2022 at 9:40

1 Answer 1

2

You can use the as_string method to turn the Composed query into a string that you can pass to Pandas (docs).

import pandas as pd
import psycopg2
from sqlalchemy import create_engine

engine = create_engine('postgresql+psycopg2://user:pw@host:port/db')
cur = engine.raw_connection().cursor()

query = psycopg2.sql.SQL('select * from {schema}.{table}') \
                        .format(schema = psycopg2.sql.Identifier('public'),
                                table = psycopg2.sql.Identifier('table_name'))
query_string = query.as_string(cur)

pd.read_sql_query(query_string, engine)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.