2

I am trying to call table_name in my SQL query using the 'new' secure way (it is good against SQL injection attacks) as in here: http://initd.org/psycopg/docs/sql.html#module-psycopg2.sql but I can't make it work with my code (table_name is a parameter of my function).

import pandas as pd
import psycopg2 as pg
import pandas.io.sql as psql
from psycopg2 import sql

sql_query = sql.SQL("SELECT * FROM {} limit %d offset %d" % (table_name, chunk_size, offset)).format(sql.Identifier(table_name)) 
df = psql.read_sql_query(sql_query, connection)

Any suggestions?

UPDATE (after a suggested answer):

I tried with

def import_table(self, connection, table_name, chunk_size, offset):
    sql = "SELECT * FROM {} limit %d offset %d" 
    qry = sql.format(**dict(table=table_name)) %(chunk_size, offset)
    df_piece = psql.read_sql_query(qry, connection)

And then calling it with:

df = pd.concat(import_table(pg.connect("dbname=my_db user=my_user"), 'table_name', 100000, 0))

But I am getting an error:

---> 30             qry = sql_ct.format(**dict(table=table_name)) %  (chunk_size, offset)
 31             df_piece = psql.read_sql_query(qry, connection)
 32 

IndexError: tuple index out of range

1 Answer 1

2

Table names/column names can't be parameterized this way.

It can and should be applied to values.

Please read about Prepared statement

Consider the following technique:

# param. for str format:      vvvvv
In [9]: qry = "SELECT * FROM {table} limit %d offset %d"

In [10]: qry.format(**dict(table='my_table')) %(10, 500)
Out[10]: 'SELECT * FROM my_table limit 10 offset 500'

UPDATE:

In [53]: my_table = 'table_name'

In [54]: qry
Out[54]: 'SELECT * FROM {table} limit %d offset %d'

In [55]: qry.format(**dict(table=my_table)) %(10, 500)
Out[55]: 'SELECT * FROM table_name limit 10 offset 500'
Sign up to request clarification or add additional context in comments.

3 Comments

I updated my answer with a trial per your suggestion and an error I get.
@SLackA, you missed parameter name table in {table} - you used {}. replace "SELECT * FROM {} limit %d offset %d" with "SELECT * FROM {table} limit %d offset %d"
I can see what you are saying but we are having a difference in our code. I need to pass my_table as a variable in qry.format(**dict(table='my_table')) %(10, 500), not as a string. I am trying to do qry.format(**dict(table=my_table)) %(10, 500) and getting another error now 28 sql_ct = "SELECT * FROM {table_name} limit %d offset %d" ---> 29 qry = sql_ct.format(**dict(table=table_name)) %(chunk_size, offset) 30 df_piece = psql.read_sql_query(qry, connection) 31 KeyError: 'table_name'

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.