Python: No se pueden concatenar objetos str y NoneType

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 + """' ) """; 

Tengo el siguiente código y Python sigue arrojando el error de que canonea cadenas de concatenación y objetos que no son de tipo. La cosa es que he verificado que cada variable aquí es, de hecho, una cadena y no es nula. He estado atrapado en esto durante bastante tiempo hoy, y cualquier ayuda sería muy apreciada.

Utilice variables de enlace en su lugar. Aquí está la especificación para trabajar con bases de datos en Python: PEP 249: Especificación de API de base de datos de Python v2.0 .

ACTUALIZACIÓN: Basado en los documentos de pymssql , necesita algo como:

 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) 

Todas estas respuestas hasta ahora no se centran en su problema sino en lo que es correcto hacer. Sí, sí, las variables de unión son mejores y más seguras. Y sí, usar% para formatear es más rápido y probablemente mejor.

Pero en su pregunta, ¿qué le da ese error? Debe ser que uno de los valores es Ninguno en algún punto, no hay otra explicación. Solo ponga una impresión de depuración delante de eso, algo como:

 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 

Apuesto a que imprimirá algo en algún momento 😉

Componer la consulta SQL de esta manera es muy peligroso, especialmente debido a la inyección de SQL

Si usando MySqldb una mejor alternativa sería así:

 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]) 

Voy a asumir que estás usando una biblioteca como MySQLdb. La mejor manera de manejar este tipo de declaraciones es así:

 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]) 

De esta manera, la biblioteca de la base de datos se encarga de ingresar correctamente los valores en la consulta INSERT. Incluso hará que los valores de Ninguno se ingresen como NULL en la nueva fila. Además, la forma original en que lo hacías era bastante susceptible a los ataques de inyección de SQL.

Si no está utilizando mysql, su biblioteca probablemente tenga una funcionalidad similar.

EDITAR –

Si se está conectando a una base de datos de SQL Server, use la biblioteca pyodbc. Puede obtenerlo en http://code.google.com/p/pyodbc/ . Aquí es cómo se vería el código:

 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() 

No debe estar concatenando valores en sentencias de SQL, ya que hacerlo lo deja abierto a la inyección de SQL (accidental o deliberada). En su lugar, debería pasar declaraciones SQL con marcadores de parámetros donde deberían ir los valores, y dejar que el conector de su base de datos inserte los valores en los lugares correctos.

Todos los conectores de base de datos admiten esto de alguna forma. Por ejemplo, psycopg2 (un conector PostgreSQL que sigue la API de la base de datos de Python) aceptaría algo como esto:

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

Un beneficio adicional de hacerlo de esta manera: los valores que no son cadenas (por ejemplo, Ninguno) se convertirán automáticamente y no obtendrá el error que describió en su pregunta.