Python 在if/else语句中无法访问代码块
当使用Python 在if/else语句中无法访问代码块,python,Python,当使用if/else语句验证发现数据返回正确的状态代码时,我在循环中解析响应的代码变得完全不可访问 以下各项按预期工作。 class Circuit(Resource): def get(self, store): print('USAGE: Received a request at CIRCUIT for Store ' + store ) conn = sqlite3.connect('store-db.db') cur = conn
if/else
语句验证发现数据返回正确的状态代码时,我在循环中解析响应的代码变得完全不可访问
以下各项按预期工作。
class Circuit(Resource):
def get(self, store):
print('USAGE: Received a request at CIRCUIT for Store ' + store )
conn = sqlite3.connect('store-db.db')
cur = conn.cursor()
res = cur.execute('SELECT * FROM Circuit WHERE StoreNumber like ' + store)
for r in res:
column_names = ["StoreNumber", "MainLEC", "MainCircuitID","SprintNUA","LastMileCircuitID", "AnalogCarrier", "SignalingCluster"]
data = [r[0], r[1], r[2], r[3], r[4], r[5], r[6]]
datadict = {column_names[itemindex]:item for itemindex, item in enumerate(data)}
return(datadict, 200)
200结果:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 239
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:30:01 GMT
{
"StoreNumber": "42",
"MainLEC": "XO",
"MainCircuitID": "xx/xxx/xxxxx/ /TQW /",
"SprintNUA": "",
"LastMileCircuitID": "xx/xxxx/xxxx//PA",
"AnalogCarrier": "XO/BE",
"SignalingCluster": "ipv4:xx.2.xx.x0x"
}
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 5
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:35:53 GMT
null
HTTP/1.0 404 NOT FOUND
Content-Type: application/json
Content-Length: 10
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:37:17 GMT
"No data"
404结果(未找到数据但仍返回200)
这是可行的,但我想检查是否未找到任何数据,所以我编写了一个获取行计数的条件。下面是它的使用示例
代码示例
class Circuit(Resource):
def get(self, store):
print('USAGE: Received a request at CIRCUIT for Store ' + store )
conn = sqlite3.connect('store-db.db')
cur = conn.cursor()
res = cur.execute('SELECT * FROM Circuit WHERE StoreNumber like ' + store)
if len(list(cur)) == 0:
return('No data', 404)
else:
for r in res:
column_names = ["StoreNumber", "MainLEC", "MainCircuitID","SprintNUA","LastMileCircuitID", "AnalogCarrier", "SignalingCluster"]
data = [r[0], r[1], r[2], r[3], r[4], r[5], r[6]]
datadict = {column_names[itemindex]:item for itemindex, item in enumerate(data)}
return(datadict, 200)
200结果:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 239
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:30:01 GMT
{
"StoreNumber": "42",
"MainLEC": "XO",
"MainCircuitID": "xx/xxx/xxxxx/ /TQW /",
"SprintNUA": "",
"LastMileCircuitID": "xx/xxxx/xxxx//PA",
"AnalogCarrier": "XO/BE",
"SignalingCluster": "ipv4:xx.2.xx.x0x"
}
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 5
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:35:53 GMT
null
HTTP/1.0 404 NOT FOUND
Content-Type: application/json
Content-Length: 10
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:37:17 GMT
"No data"
数据返回为null
,使用打印测试后,我发现在中,对于res中的r:
我的代码变得不可访问。我已经核实了所有的缩进
404结果:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 239
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:30:01 GMT
{
"StoreNumber": "42",
"MainLEC": "XO",
"MainCircuitID": "xx/xxx/xxxxx/ /TQW /",
"SprintNUA": "",
"LastMileCircuitID": "xx/xxxx/xxxx//PA",
"AnalogCarrier": "XO/BE",
"SignalingCluster": "ipv4:xx.2.xx.x0x"
}
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 5
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:35:53 GMT
null
HTTP/1.0 404 NOT FOUND
Content-Type: application/json
Content-Length: 10
Access-Control-Allow-Origin: *
Server: Werkzeug/0.14.1 Python/3.7.0
Date: Thu, 15 Nov 2018 16:37:17 GMT
"No data"
计数是0
,所以我们得到了404返回值,所以我知道计数和条件都在工作
如果我把
print()
放在后面,否则:
它会运行,但循环不会。看起来cur
是一个迭代器,而res
是该迭代器的引用。当您调用list(cur)
时,它将耗尽迭代器,然后您将该数据丢弃。然后你试着遍历res
,什么都没有了,所以for循环什么都不做
显而易见的答案是:
res = list(cur)
if len(res) == 0:
return('No data', 404)
else:
for r in res:
column_names = ["StoreNumber", "MainLEC", "MainCircuitID","SprintNUA","LastMileCircuitID", "AnalogCarrier", "SignalingCluster"]
data = [r[0], r[1], r[2], r[3], r[4], r[5], r[6]]
datadict = {column_names[itemindex]:item for itemindex, item in enumerate(data)}
return(datadict, 200)
通过在光标上调用list()
,您将耗尽迭代器,只剩下else
分支可以循环使用的内容。下面的玩具代码演示了这一点,为了更好地练习,我做了一些修改:
与
一起使用,即使出现错误,它也会为我们关闭数据库.fetchall()
检索结果。尽管直接在光标上迭代比预先生成整个结果列表更有效,但除了将结果分配给有意义的名称外,它还允许您多次迭代import sqlite3
with sqlite3.connect(":memory:") as conn: # Using a context manager
c = conn.cursor()
c.execute("""
CREATE TABLE IF NOT EXISTS testing(
some_code INTEGER,
data TEXT)
""")
c.executemany("""
INSERT INTO testing VALUES (?, ?)
""", [[1, 'hi'], [2, 'bye'], [1, 'something']])
# Query the new database using a parameterized query
c.execute("select * from testing where some_code = ?", (1,))
if len(list(c)) > 0: # Exhausts the iterator and then throws the result away
print("Printing result set 1")
for row in c:
print(row)
print("End of result set 1")
print()
# Repeat the query
c.execute("select * from testing where some_code = ?", (1,))
print("Printing result set 2")
for row in c: # iterate the cursor
print(row)
print("End of result set 2")
print()
# And one more time but using fetchall()
c.execute("select * from testing where some_code = ?", (1,))
data = c.fetchall() # Exhaust the iterator but assign a list to a name
print("Printing result set 3")
for row in data:
print(row)
print("End of result set 3")
print()
# And we can keep on printing without re-querying
print("Printing result set 4")
for row in data:
print(row)
print("End of result set 4")
print()
一件非常突出的事情是,对于res:中的r,在
中有一个返回。这将立即中断函数。除此之外,res=cur.execute('SELECT*from Circuit WHERE StoreNumber like'+store)
在SQLite中不起作用,因为您在搜索字符串的任一侧都缺少%
,更不用说使用字符串连接时SQL注入的漏洞了。我想,除非你传递一个完全格式化的字符串作为参数,否则你永远不会得到任何结果。请参见如果len(列表(cur))==0:
→ if not res:
我给你的链接告诉你如何正确操作。我建议你养成一个习惯,总是用正确的方式去做;很多时候,人们认为字符串连接让他们的生活变得更轻松,但最终在这里丢弃了一些令人讨厌的转义字符串,因为它不起作用……我想我已经使用了它,等等,测试我正在尝试应用你的建议,但并不真正理解你所做的更改。通过使res
list(cur)
我应该在cur
中作为conn.cursor.execute('SLECT blah blah')
应用我的查询吗?对不起,我从未使用过sqlite
,我不知道导致这种行为的底层结构是什么。这将您的迭代器转换为一个列表,然后在该列表上执行操作。但是,在我接受之前,由于对python和sql基本上缺乏经验,使用fetchall()是否有任何差异需要注意
?@code我在下一个班次到来之前匆匆忙忙,偷走了我的办公桌:)我回家后会清理代码,并对最佳实践进行一些更改,这给了我足够的术语,可以开始研究,谢谢。:)@如果你有很多数据,有一件事值得注意。游标是一个迭代器,您可以通过它进行惰性迭代,而fetchall
将提前生成完整的列表。这与python 2中的xrange
vsrange
相同。基本上,迭代游标的效率稍高一些,如果您的表中有成百上千的行,那么这将产生不同results@CodeSpent所做的编辑。对不起,时间比我希望的要长。