我有这个方法从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
我有一个测试,但如果price
为None
,我将无法返回100。我的运行测试只返回NoneType
对象不可订阅'
我也尝试过:100 if price is None else price
,但是没有用。我错过了什么?
答案 0 :(得分:5)
您在该测试之前订阅了None
:
price = cursor.execute(sql).fetchone()[0]
.fetchone()
返回None
,None[0]
触发了异常:
>>> None[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable
错误消息告诉您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]
或者,您可以使用元组赋值和使用异常处理来返回默认值:
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
您还应不使用字符串格式将数据与查询相结合。使用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
查询中的每个%s
都是一个占位符,这些占位符的值作为第二个参数传递给cursor.execute()
调用。然后,数据库驱动程序负责正确引用每列的值,确保数据不能作为SQL命令执行;请注意,%s
列的EffectiveDate
占位符周围没有引号。这样可以避免SQL注入攻击,并使数据库驱动程序可以重用给定查询的查询计划,这对数据库更有效。
答案 1 :(得分:2)
您正在尝试访问0
的索引price
,然后再检查它是None
,从而尝试访问None[0]
。
price = cursor.execute(sql).fetchone()[0]
# this may very well be None ---^
您应该抓取,检查price
是否不是None
,然后才订阅它。
price = cursor.execute(sql).fetchone()
return price[0] if price is not None else 100
作为旁注,您应该检查price
是None
,而不是NoneType
,这是其类型。要使用NoneType
,您需要检查if isinstance(price, NoneType)
,但这不是针对None
检查对象的方式。
答案 2 :(得分:-1)
return 100 if price is None else price
这个简单的if
会检查None
的值并返回所需的结果。我最初使用if price
执行此操作,但是当价格为0 - 0时,这也不起作用{。{1}}。