Newbie needs Help

johnzenger at gmail.com johnzenger at gmail.com
Thu Aug 17 00:09:19 EDT 2006


Also, it may be easier to use string interpolation, as in:

return "INSERT INTO statecode (state, name) VALUES ('%(state)s',
'%(name)s')" % insert_dict

...after all necessary escaping, of course.

John Machin wrote:
> len wrote:
> > Hi all
> >
> > I am writing a python program that inserts records into a database on
> > XP using mxODBC.
> >
> > I need to write a section of code which will create the following SQL
> > command as an example;
> >
> > INSERT INTO statecode (state, name) VALUES ('IL', 'Illinois')
> >
> > This statement will be built up using the following code;
> >
> > import mx.ODBC
> > import mx.ODBC.Windows
> > def insertFromDict(table, dict):
> >     """Take dictionary object dict and produce sql for
> >     inserting it into the named table"""
> >     sql = 'INSERT INTO ' + table
> >     sql += ' ('
> >     sql += ', '.join(dict)
> >     sql += ') VALUES ('
> >     sql += ', '.join(map(dictValuePad, dict))     # ??? this code does
> > NOT format correctly
> >     sql += ')'
> >     return sql
> >
> > def dictValuePad(key):                                # ??? this code
> > does Not format correctly
> >     return "'" + str(key) + "'"
> >
> > db = mx.ODBC.Windows.DriverConnect('dsn=UICPS Test')
> > c = db.cursor()
> > insert_dict = {'state':'IL', 'name':'Illinois'}
> > sql = insertFromDict("statecode", insert_dict)
> > print sql
> > c.execute(sql)
> >
>
> The code below will do what you say that you want to do -- so long as
> all your columns are strings (varchar or whatever in SQL terms).
> Otherwise IMHO you would be much better off doing it this way:
>     sql = "insert into policy (type, premium) values(?, ?)"
>     data = ('building', 123.45)
>     cursor.execute(sql, data)
> for two reasons:
> (1) let the ODBC kit worry about formatting dates, strings with
> embedded single quotes, etc
> (2) it can be more efficient; the sql is constant and needs to be
> parsed only once
> (3) [bonus extra reason] the way you are doing it is vulnerable to
> what's called an "SQL injection attack"; although you have no doubt
> eyeballed all the data, doing it that way is a bad habit to get into.
>
> You should be able to modify the supplied code very easily to produce
> the sql variety with "?" in it.
>
> HTH,
> John
>
> C:\junk>type sqlinsdict.py
> def sqlquote(astring):
>     return "'" + astring.replace("'", "''") + "'"
>
> def insertFromDict(table, adict):
>     """Take dictionary object dict and produce sql for
>     inserting it into the named table.
>     Sample input:
>     insert_dict = {'state':'IL', 'name':'Illinois'}
>     sql = insertFromDict("statecode", insert_dict)
>     Required output:
>     INSERT INTO statecode (state, name) VALUES ('IL', 'Illinois')
>     """
>
>     t = [
>         'INSERT INTO ',
>         table,
>         ' (',
>         ', '.join(adict.keys()),
>         ') VALUES (',
>         ', '.join(sqlquote(x) for x in adict.values()),
>         ')',
>         ]
>     return ''.join(t)
>
> if __name__ == "__main__":
>     tests = [
>         ('IL', 'Illinois'),
>         ('OH', "O'Hara"),
>         ]
>     cols = ['state', 'name']
>     for test in tests:
>         the_dict = dict(zip(cols, test))
>         print the_dict
>         print insertFromDict('statecode', the_dict)
>
> C:\junk>sqlinsdict.py
> {'state': 'IL', 'name': 'Illinois'}
> INSERT INTO statecode (state, name) VALUES ('IL', 'Illinois')
> {'state': 'OH', 'name': "O'Hara"}
> INSERT INTO statecode (state, name) VALUES ('OH', 'O''Hara')




More information about the Python-list mailing list