0

i have a written the below function to filter a column in a sql query, the function takes a string argument which will be inputted in the 'where clause'

def summaryTable(machineid):
 df=pd.read_sql(""" SELECT fld_ATM  FROM [003_tbl_ATM_Tables] 
    WHERE (LINK <> 1) AND (fld_ATM =('machineid')) ;
     """,connection)
connection.close()
return df

the function returns an empty Dataframe. i know the query itself is correct 'cause i get the expected data when i 'hardcode' the machine id

4
  • 'machineid' seems to be part of the string as a word, not a variable. You should use a formatter (see pyformat.info) to pass the machineid as a string-variable into your query Commented May 22, 2018 at 13:01
  • 2
    @offeltoffel No, they should not use string formatting for passing variables to SQL queries. It's a habit that will bite in the long run (read about SQL injection). Commented May 22, 2018 at 13:05
  • 1
    Could you please include the definition of connection, or in other words what DB-API driver you are using, if not using SQLAlchemy. Commented May 22, 2018 at 13:11
  • 1
    Hi Ilja. i am using - connection=pyodbc.connect() and passing the normal parameters ie server details etc Commented May 22, 2018 at 13:24

2 Answers 2

2

Use params to pass a tuple of parameters including machineid to read_sql. pyodbc replaces the ? character in your query with parameters from the tuple, in order. Their values will be safely substituted at runtime. This avoids dangerous string formatting issues which may result in SQL injection.

df = pd.read_sql(""" SELECT fld_ATM  FROM [003_tbl_ATM_Tables] 
                     WHERE (LINK <> 1) AND (fld_ATM = ?) ;
                 """, connection, params=(machineid,)) 
Sign up to request clarification or add additional context in comments.

3 Comments

this doesn't work , i get the following error ('The SQL contains 0 parameter markers, but 1 parameters were supplied', 'HY000')
:name style placeholders aren't widely supported by DB-API drivers, and pyodbc is no exception. It's more of an SQLAlchemy thing.
Fixed to avoid use of named parameters.
1

You need to add machineid to query using params.

# ? is the placeholder style used by pyodbc. Some use %s, for example.
query = """ SELECT fld_ATM  FROM [003_tbl_ATM_Tables] 
        WHERE (LINK <> 1) AND (fld_ATM = ?) ;
         """
data_df = pd.read_sql_query(query, engine, params=(machineid, ))

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.