Python / pypyODBC:使用字符串和 NULL 插入行
Python / pypyODBC: Row Insert Using String and NULLs
我是 Python 的新手,在当前项目之前还没有真正接触过 SQL 服务器和 XML 解析(甚至可能不是最好的方法)。长话短说,我的 IT 团队积压很多,我需要将数据放入沙箱 table(从 XML 解析)。
XML 中有一段包含属性 [xx]001 到 [xx]025。并非所有这些属性都包含在我将要解析的每个 XML 中。因此,我遍历所有可能属性的循环并将结果附加到列表中。由于并非所有属性都在每个 XML 中,我可以通过尝试表示每个属性来招致 noneTypes。在开始创建我的 SQL 插入语句之前,这不是问题,我需要将它们转换为 NULL。可能有一些非常简单的方法来处理这个问题,但我的新手身份阻碍了我的进步。相关代码片段如下...
也许有更好的方法?我担心 sqlList 可能只能在我达到限制之前变得如此之大。
#this list contains Nones
sqlList = (", ".join(map(repr,appendedList)))
#the Nones are an issue when I get to here
curs.execute("USE Sandbox INSERT INTO myTable VALUES (%s)" % (sqlList))
curs.commit()
下面是 sqlList 的示例:
'20_2014', '20_2014_3/25/2015 2:01 PM', 'FBR', 'A', '0', '0', '3', '1', '134', None, None, '0', None, '0', '0', '0', '0', '0', None, None, '2', None, None, None, None
我收到以下错误消息:
pypyodbc.ProgrammingError: ('42S22', "[42S22] [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'None'.")
没关系。见下文:
#this string contains Nones
sqlList = (", ".join(map(repr,appendedList)))
#this converts Nones to NULLs
sqlList = sqlList.replace("None", "NULL")
#all good now
curs.execute("USE Sandbox INSERT INTO myTable VALUES (%s)" % (sqlList))
curs.commit()
总的来说还是想知道这是否是 "right" 的方法。
In general would still like to know if this is the "right" way to do this.
您的解决方案仍然是 动态 SQL,它总是受到
的影响
- SQL 注入问题(例如,如果其中一个字符串包含单引号怎么办?),
- 类型杂耍(例如,None -> NULL,如您的问题),
- 必须为文字值(字符串、日期等)使用正确的分隔符
如果您使用参数化查询,所有这些问题都会消失。为清楚起见,此示例仅使用 2 个属性(而不是您问题中的 25 个),但原理完全相同。请注意,我不必执行任何特殊操作来处理 None
值,以便将它们作为 NULL 插入。
import pypyodbc
myData = [
(1, 'foo'),
(2, None),
(3, 'bar'),
]
connStr = """
DSN=myDb_SQLEXPRESS;
"""
cnxn = pypyodbc.connect(connStr)
crsr = cnxn.cursor()
sql = """
INSERT INTO myTable VALUES (?, ?)
"""
for dataRow in myData:
print(dataRow)
crsr.execute(sql, dataRow)
cnxn.commit()
crsr.close()
cnxn.close()
控制台输出是...
(1, 'foo')
(2, None)
(3, 'bar')
... 并且三行正确插入到 table 中,包括第二行中的 NULL (None)。
我是 Python 的新手,在当前项目之前还没有真正接触过 SQL 服务器和 XML 解析(甚至可能不是最好的方法)。长话短说,我的 IT 团队积压很多,我需要将数据放入沙箱 table(从 XML 解析)。
XML 中有一段包含属性 [xx]001 到 [xx]025。并非所有这些属性都包含在我将要解析的每个 XML 中。因此,我遍历所有可能属性的循环并将结果附加到列表中。由于并非所有属性都在每个 XML 中,我可以通过尝试表示每个属性来招致 noneTypes。在开始创建我的 SQL 插入语句之前,这不是问题,我需要将它们转换为 NULL。可能有一些非常简单的方法来处理这个问题,但我的新手身份阻碍了我的进步。相关代码片段如下...
也许有更好的方法?我担心 sqlList 可能只能在我达到限制之前变得如此之大。
#this list contains Nones
sqlList = (", ".join(map(repr,appendedList)))
#the Nones are an issue when I get to here
curs.execute("USE Sandbox INSERT INTO myTable VALUES (%s)" % (sqlList))
curs.commit()
下面是 sqlList 的示例:
'20_2014', '20_2014_3/25/2015 2:01 PM', 'FBR', 'A', '0', '0', '3', '1', '134', None, None, '0', None, '0', '0', '0', '0', '0', None, None, '2', None, None, None, None
我收到以下错误消息:
pypyodbc.ProgrammingError: ('42S22', "[42S22] [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'None'.")
没关系。见下文:
#this string contains Nones
sqlList = (", ".join(map(repr,appendedList)))
#this converts Nones to NULLs
sqlList = sqlList.replace("None", "NULL")
#all good now
curs.execute("USE Sandbox INSERT INTO myTable VALUES (%s)" % (sqlList))
curs.commit()
总的来说还是想知道这是否是 "right" 的方法。
In general would still like to know if this is the "right" way to do this.
您的解决方案仍然是 动态 SQL,它总是受到
的影响- SQL 注入问题(例如,如果其中一个字符串包含单引号怎么办?),
- 类型杂耍(例如,None -> NULL,如您的问题),
- 必须为文字值(字符串、日期等)使用正确的分隔符
如果您使用参数化查询,所有这些问题都会消失。为清楚起见,此示例仅使用 2 个属性(而不是您问题中的 25 个),但原理完全相同。请注意,我不必执行任何特殊操作来处理 None
值,以便将它们作为 NULL 插入。
import pypyodbc
myData = [
(1, 'foo'),
(2, None),
(3, 'bar'),
]
connStr = """
DSN=myDb_SQLEXPRESS;
"""
cnxn = pypyodbc.connect(connStr)
crsr = cnxn.cursor()
sql = """
INSERT INTO myTable VALUES (?, ?)
"""
for dataRow in myData:
print(dataRow)
crsr.execute(sql, dataRow)
cnxn.commit()
crsr.close()
cnxn.close()
控制台输出是...
(1, 'foo')
(2, None)
(3, 'bar')
... 并且三行正确插入到 table 中,包括第二行中的 NULL (None)。