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
分支可以循环使用的内容。下面的玩具代码演示了这一点,为了更好地练习,我做了一些修改:

  • 我将
    一起使用,即使出现错误,它也会为我们关闭数据库
  • 我使用参数化查询来检索值;这些将有助于防止SQL注入
  • 我已经演示了如何使用
    .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
    vs
    range
    相同。基本上,迭代游标的效率稍高一些,如果您的表中有成百上千的行,那么这将产生不同results@CodeSpent所做的编辑。对不起,时间比我希望的要长。