-1 python
我有这个方法从SQL查询中检索一个值:
def get_base_price(self, date):
sql = """
SELECT TimeSeriesValue
FROM dbo.TimeSeriesPosition
WHERE
TimeSeriesTypeID = {0} AND
FundID = {1} AND
SecurityMasterID = 45889 AND
EffectiveDate = '{2}'""".format(self.LAST_PRICE_ID, self.FUND_ID, date)
with self.job.rap.connect() as conn:
with conn.cursor() as cursor:
price = cursor.execute(sql).fetchone()[0]
if price is NoneType:
return 100
else:
return price # Returns base price value
Run Code Online (Sandbox Code Playgroud)
我有一个测试,但如果price是的话,我无法返回100 None.我的运行测试只返回NoneType对象不可订阅'
我也尝试过:100 if price is None else price那没用.我错过了什么?
您None 在该测试之前订阅:
price = cursor.execute(sql).fetchone()[0]
Run Code Online (Sandbox Code Playgroud)
.fetchone()返回None,它None[0]触发异常:
>>> None[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)
该错误消息告诉您类型None,即NoneType不实现订阅支持.如果仔细观察Python打印出来的回溯,你会发现它price = cursor.execute(sql).fetchone()[0]是抛出异常的行,代码永远不会到达后面的if price is ...行.
打电话.fetchone()没有订阅,然后测试None:
with self.job.rap.connect() as conn:
with conn.cursor() as cursor:
cursor.execute(sql)
price_row = cursor.fetchone()
if price_row is None:
return 100
else:
return price_row[0]
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用元组赋值并使用异常处理来返回默认值:
with self.job.rap.connect() as conn:
with conn.cursor() as cursor:
cursor.execute(sql)
try:
price, = cursor.fetchone()
return price
except TypeError:
return 100
Run Code Online (Sandbox Code Playgroud)
您也不应该使用字符串格式将数据与查询组合.使用SQL参数:
sql = """
SELECT TimeSeriesValue
FROM dbo.TimeSeriesPosition
WHERE
TimeSeriesTypeID = %s AND
FundID = %s AND
SecurityMasterID = %s AND
EffectiveDate = %s"""
with self.job.rap.connect() as conn:
with conn.cursor() as cursor:
cursor.execute(sql, (self.LAST_PRICE_ID, self.FUND_ID, date))
try:
price, = cursor.fetchone()
return price
except TypeError:
return 100
Run Code Online (Sandbox Code Playgroud)
%s查询中的每个都是占位符,并且这些占位符的值cursor.execute()作为第二个参数传递给调用.然后,数据库驱动程序负责正确引用每列的值,确保数据不能作为SQL命令执行; 请注意,列的%s占位符周围没有引号EffectiveDate.这使您可以避免SQL注入攻击,并使数据库驱动程序可以重用给定查询的查询计划,这对数据库更有效.