简体   繁体   中英

Python MySQLdb TypeError: not all arguments converted during string formatting

Upon running this script:

#! /usr/bin/env python
import MySQLdb as mdb
import sys    

class Test:
    def check(self, search):
        try:
            con = mdb.connect('localhost', 'root', 'password', 'recordsdb');

            cur = con.cursor()
            cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", search )

            ver = cur.fetchone()

            print "Output : %s " % ver

        except mdb.Error, e:

            print "Error %d: %s" % (e.args[0],e.args[1])
            sys.exit(1)

        finally:    
            if con:    
                con.close()

test = Test()
test.check("test")

Instead of this:

cur.execute( "SELECT * FROM records WHERE email LIKE '%s'", search )

You can try this code:

cur.execute( "SELECT * FROM records WHERE email LIKE %s", (search,) )

'%' keyword is so dangerous because it major cause of 'SQL INJECTION ATTACK'.
So you just using this code.

cursor.execute("select * from table where example=%s", (example,))
cur.execute( "SELECT * FROM records WHERE email LIKE %s", (search,) )

The accepted answer by @kevinsa5 is correct, but you might be thinking "I swear this code used to work and now it doesn't," and you would be right.

There was an API change in the MySQLdb library between 1.2.3 and 1.2.5. The 1.2.3 versions supported

cursor.execute("SELECT * FROM foo WHERE bar = %s", 'baz')

but the 1.2.5 versions require

cursor.execute("SELECT * FROM foo WHERE bar = %s", ['baz'])

as the other answers state. I can't find the change in the changelogs, and it's possible the earlier behavior was considered a bug.

The Ubuntu 14.04 repository has python-mysqldb 1.2.3, but Ubuntu 16.04 and later have python-mysqldb 1.3.7+.

If you're dealing with a legacy codebase that requires the old behavior but your platform is a newish Ubuntu, install MySQLdb from PyPI instead:

$ pip install MySQL-python==1.2.3

I don't understand the first two answers. I think they must be version-dependent. I cannot reproduce them on MySQLdb 1.2.3, which comes with Ubuntu 14.04LTS. Let's try them. First, we verify that MySQL doesn't accept double-apostrophes:

mysql> select * from methods limit 1;
+----------+--------------------+------------+
| MethodID | MethodDescription  | MethodLink |
+----------+--------------------+------------+
|       32 | Autonomous Sensing | NULL       |
+----------+--------------------+------------+
1 row in set (0.01 sec)

mysql> select * from methods where MethodID = ''32'';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '9999'' ' at line 1

According PEP8,I prefer to execute SQL in this way:

cur = con.cursor()
# There is no need to add single-quota to the surrounding of `%s`,
# because the MySQLdb precompile the sql according to the scheme type
# of each argument in the arguments list.
sql = "SELECT * FROM records WHERE email LIKE %s;"
args = [search, ]
cur.execute(sql, args)

I encountered this error while executing SELECT * FROM table;<\/code> I traced the error to cursor.py line 195.

if args is not None:
        if isinstance(args, dict):
            nargs = {}
            for key, item in args.items():
                if isinstance(key, unicode):
                    key = key.encode(db.encoding)
                nargs[key] = db.literal(item)
            args = nargs
        else:
            args = tuple(map(db.literal, args))
        try:
            query = query % args
        except TypeError as m:
            raise ProgrammingError(str(m))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM