Python:无法连接str和NoneType对象

时间:2010-06-17 17:56:17

标签: python sql

sql = """
        INSERT INTO [SCHOOLINFO] 
        VALUES(
            '""" + self.accountNo + """', 
            '""" + self.altName + """',
            '""" + self.address1 + """',
            '""" + self.address2 + """',
            '""" + self.city + """',
            '""" + self.state + """',
            '""" + self.zipCode + """',
            '""" + self.phone1 + """',
            '""" + self.phone2 + """',
            '""" + self.fax + """',
            '""" + self.contactName + """',
            '""" + self.contactEmail + """',
            '""" + self.prize_id + """',
            '""" + self.shipping + """',
            '""" + self.chairTempPass + """',
            '""" + self.studentCount + """'
        )
    """;

我有以下代码,Python不断抛出错误,它可以连接字符串和非类型对象。问题是我已经验证了这里的每个变量实际上都是一个字符串而且不是null。我今天已经坚持了很长一段时间,任何帮助都将不胜感激。

5 个答案:

答案 0 :(得分:4)

请改用绑定变量。以下是在Python中使用DB的规范:PEP 249: Python Database API Specification v2.0

更新:根据pymssql的文档,您需要以下内容:

sql = """
    INSERT INTO [SCHOOLINFO] 
    VALUES(
        %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s, %s, %d
    )"""
cur.execute(sql, self.accountNo, self.altName, self.address1, self.address2, self.city, self.state, self.zipCode, self.phone1, self.phone2, self.fax, self.contactName, self.contactEmail, self.prize_id, self.shipping, self.chairTempPass, self.studentCount)

答案 1 :(得分:2)

到目前为止,所有这些答案都不是关注您的问题,而是关注正确的问题。是的,是的 - 绑定变量更好,更安全。是的,使用%进行格式化更快,可能更好。

但是在你的问题上是什么给了你那个错误 - 它必须是某个值之一,在某些时候是没有,没有其他解释。只需将调试打印放在其前面,例如:

for v in 'accountNo altName address1 address2 city state zipCode phone1 phone2 fax contactName contactEmail prize_id shipping chairTempPass studentCount'.split():
    if getattr(self, v) is None:
        print 'PANIC: %s is None' % v

我打赌它会在某些时候印出一些东西; - )

答案 2 :(得分:1)

像这样编写SQL查询非常危险,特别是由于sql-injection

如果使用MySqldb,更好的选择是这样的:

db.query("INSERT INTO [SCHOOLINFO] VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
[self.accountNo, self.altName, self.address1, self.address2, self.city, self.state, self.zipCode, self.phone1, self.phone2, self.fax, self.contactName, self.contactEmail, self.prize_id, self.shipping, self.chairTempPass, self.studentCount])

答案 3 :(得分:1)

我假设您正在使用像MySQLdb这样的库。处理这类语句的最佳方法是:

import _mysql

db = _mysql.connect("localhost","user","password","database_name")
cursor = db.cursor()

sql = """
    INSERT INTO [SCHOOLINFO] 
    VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
cursor.execute(sql, [self.accountNo, self.altName, self.address1, \
                     self.address2, self.city, self.state, self.zipCode, \
                     self.phone1, self.phone2, self.fax, self.contactName, \
                     self.contactEmail, self.prize_id, self.shipping, \
                     self.chairTempPass, self.studentCount])

这样,数据库库就可以正确输入INSERT查询中的值。它甚至会将None值作为NULL输入到新行中。加上你原来这样做的方式很容易受到SQL注入攻击。

如果您不使用mysql,您的库可能具有类似的功能。

编辑 -

如果要连接到SQL Server数据库,请使用pyodbc库。你可以在http://code.google.com/p/pyodbc/获得它。这是代码的样子:

import pyodbc

conn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=database_name;UID=user;PWD=password')
cursor = conn.cursor()

sql = """
    INSERT INTO [SCHOOLINFO] 
    VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"""
cursor.execute(sql, self.accountNo, self.altName, self.address1, \
                     self.address2, self.city, self.state, self.zipCode, \
                     self.phone1, self.phone2, self.fax, self.contactName, \
                     self.contactEmail, self.prize_id, self.shipping, \
                     self.chairTempPass, self.studentCount)
conn.commit()

答案 4 :(得分:0)

您不应该将值连接到SQL语句中,因为这样做会让您({偶然的或故意的)SQL injection完全开放。相反,您应该传递带有值的参数标记的SQL语句,并让数据库连接器将值插入到正确的位置。

所有数据库连接器都以某种形式支持此功能。例如,psycopg2(遵循Python DB API的PostgreSQL连接器)将接受以下内容:

cursor.execute( "insert into schoolinfo (accountno, altname) values (%s, %s)",
    (self.accountNo, self.altName))

这样做的一个附带好处:非字符串的值(例如无)将自动转换,您将不会得到您在问题中描述的错误。