由于某种原因,当我运行以下脚本时,没有任何TypeError
例外,并且我的应用程序运行没有问题。 (我将sqlite3用于数据库,将Flask用于应用程序本身。)
my_list = []
for dat in data:
c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
my_list.append(c.fetchone()[0])
return my_list
似乎对于某些日期而言,没有任何数据,因此偶尔有NoneType
是完全可能的。问题是,当我将代码更改为以下代码时,即会出现NoneType not subscriptable
错误。
my_list = []
for dat in data:
c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
try:
my_list.append(round(c.fetchone()[0]))
except:
my_list.append(c.fetchone()[0])
return my_list
假设,如果它遇到一个NoneType
对象,它将分支到except
子句,然后得到与原始代码块相同的结果。相反,我得到了这个错误,它破坏了我的Flask应用程序。如果有人可以解释发生了什么,那就太好了!
答案 0 :(得分:1)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'spamfilter',
'USER': 'sa',
'PASSWORD': 'xxxxxxx',
'HOST': '192.168.2.10', # Or an IP Address that your DB is hosted on
'PORT': '49170',
'CONN_MAX_AGE': 60,
}
}
可以返回c.fetchone()
。如果您的None
查询仅产生一行,而和如果SELECT
引发了异常,则再次调用round()
可能会导致c.fetchone()
在None
处理程序中返回。这里的问题是多次调用except
不会导致相同的第一行返回给后续调用。
调用一次c.fetchone()
,并在执行任何操作之前测试它是否返回了c.fetchone()
以外的值:
None
请注意,使用总括c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
row = c.fetchone()
if row is not None:
try:
my_list.append(round(row[0]))
except ValueError: # value that can't be rounded
continue
语句几乎总是一个坏主意。仅捕获预期的异常,仅此而已。您现在可以轻松地掩盖内存错误或阻止中断。
旁注:您对SQL injection attacks敞开大门。 不要使用字符串格式插入值,始终使用SQL参数来使数据库驱动程序适当地转义值:
except
c.execute("""SELECT some_data FROM data_table WHERE date=?""", (dat,))
问号是一个SQL参数占位符,元组作为参数的第二个参数传入。