2

Possible Duplicate:
Python challenging string encoding

I am trying to put a list of tickers into a SQL query. I am new to Python.

cus is a list set up as ['x', 'y', ..., 'a']

test = psql.frame_query(
    "select * from dataBase where cus IN (%r)", con = db) % cus

I tried this and it failed.

My next attempt was to try and remove the brackets and then paste the list in. How do I remove the brackets so that I get:

cus2 = 'x', 'y', ..., 'a'

I was going to do:

str = "select * from dataBase where cus IN (%r)" % cus2
test2 = psql.frame_query(str, con = db)

Or is there another way I should be attempting this?

Thank you.

1
  • To summarize: Do not use string interpolation (%) to include values in a SQL query. Use SQL parameters instead; pandas.io.sql supports parameters directly. Commented Dec 18, 2012 at 16:23

1 Answer 1

4

With SQL, you really want to avoid just inserting your value into the query. You normally leave that to the database adapter, which has specialized knowledge about how to avoid creating dangerous SQL from your values (SQL quotation escaping, a.k.a. SQL injection attacks).

Unfortunately, the pandas.io.sql module has only half-heartedly implemented parameter support.

Instead of using frame_query, just use DataFrame.from_records() directly.

First, generate the SQL query with parameters. The format of the SQL parameters differs from database adapter to database adapter, since the Python DB API standard allows for a few variants. I'll assume you are using MySQL here, which uses %s for positional parameters, echoing Python's syntax:

sql = "select * from dataBase where cus IN ({0})".format(', '.join(['%s'] * len(cus2)))

That creates enough parameters for each of the values in cus2. Then query the database:

cur = psql.execute(sql, con, params=cus2)
rows = cur.fetchall()
columns = [col_desc[0] for col_desc in cur.description]
cur.close()

result = DataFrame.from_records(rows, columns=columns, coerce_float=True)

Since you appear to be using the Sybase module module for your connection, you'll have to adjust this for the (somewhat non-standard) SQL parameter syntax that library uses. It only accepts named parameters, which use the form @name:

params = dict(('@param{0}'.format(i), v) for i, v in enumerate(cus2))
sql = "select * from dataBase where cus IN ({0})".format(
    ', '.join(sorted(params.keys())))

cur = psql.execute(sql, con, params=params)
rows = cur.fetchall()
columns = [col_desc[0] for col_desc in cur.description]
cur.close()

result = DataFrame.from_records(rows, columns=columns, coerce_float=True)
Sign up to request clarification or add additional context in comments.

8 Comments

One follow-up: for the cur = psql.execute(sql, con, params=cus2) line, I am getting an error that says: AttributeError: 'list' object has no attribute 'items' currently the list is set up ['x', 'y', ... ]
@user1911092: what database are you connecting to?
A database that I have here at school If I remove the params piece and just enter a string with the cus written out - the test works
and what library is used to connect to sybase?
I use the pandas.io.sql at this point. I am not sure if I am answering your question though.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.