【问题标题】:Loop works fine but when sqlite execute called it stops after first line循环工作正常,但是当调用 sqlite 执行时,它在第一行之后停止
【发布时间】:2021-12-09 17:37:59
【问题描述】:

这是 Python for Everyone 数据可视化项目的第一阶段。 我无法弄清楚为什么循环在第 90-91 行的 SQL 命令期间停止工作。 我已经逐段对其进行了测试,如果您注释掉最后一个 MySQL 命令,则循环可以正常工作,但是当您将它们保留在其中添加一个成功的行后,它会停止工作。

import urllib.request, urllib.parse, urllib.error
import sqlite3
import json
import ssl

api_key = "800a5c3b"
serviceurl = "http://www.omdbapi.com/?"

conn = sqlite3.connect('omdb.sqlite')
cur = conn.cursor()

cur.execute('DROP TABLE IF EXISTS Omdbdump;')
cur.execute('''CREATE TABLE Omdbdump (
    id  INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
title TEXT, year TEXT, rated TEXT, released TEXT, runtime TEXT, genre TEXT, director TEXT, writer TEXT, actors TEXT, plotlong TEXT, language  TEXT, country TEXT, awards TEXT, poster URL, imdbrating REAL, rtrating REAL, mcrating REAL, imdbid TEXT, type TEXT, dvd TEXT, boxoffice TEXT, production TEXT, website URL)
''')

# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

fh = cur.execute('''SELECT id, title, year FROM top50''')

rty = list()
for row in fh:
    #row = cur.fetchone()
    qtitle = str(row[1])
    qyear = str(row[2])

    #print(rty)
    print(qtitle)
    print(qyear)

    #parms sets up the query url: url concatenated with address and api key
    #query format https://www.omdbapi.com/?t=blade+runner&y=2018&plot=full&apikey=800a5c3b

    parms = dict()
    parms["t"] = qtitle
    parms["y"] = qyear
    parms["plot"] = "full"
    parms["apikey"] = api_key
    url = serviceurl + urllib.parse.urlencode(parms)

    print('Retrieving', url)
    uh = urllib.request.urlopen(url, context=ctx)
    data = uh.read().decode()
    print('Retrieved', len(data), 'characters', data[:20].replace('\n', ' '))
    
    js = json.loads(data)
    if js['Response'] == 'False':
        print('==== Failure To Retrieve ====')
        print(data)
        continue
   
    title = js['Title']
    year = js['Year']
    rated = js['Rated']
    released = js['Released']
    runtime = js['Runtime']
    genre = js['Genre']
    director = js['Director']
    writer = js['Writer']
    actors = js['Actors']
    plotlong = js['Plot']
    language = js['Language']
    country = js['Country']
    awards = js['Awards']
    poster = js['Poster']
    imdbrating = js['imdbRating']
    mcrating = js['Metascore']
    imdbid = js['imdbID']
    type = js['Type']
    dvd = js['DVD']
    boxoffice = js['BoxOffice']
    production = js['Production']
    website = js['Website']
    try:
        rtrating = js['Ratings'][1]['Value']
    except:
        rtrating = 'N/A'
    
    print(title)
    print(imdbid)
    print(runtime)
    
    #the loop works until here -- with the following lines, it goes through once then stops...
    
    cur.execute('''INSERT INTO Omdbdump (title, year, rated, released, runtime, genre, director, writer, actors, plotlong, language, country, awards, poster, imdbrating, rtrating, mcrating, imdbid, type, dvd, boxoffice, production, website) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )''', (title, year, rated, released, runtime, genre, director, writer, actors, plotlong, language, country, awards, poster, imdbrating, rtrating, mcrating, imdbid, type, dvd, boxoffice, production, website) )
    conn.commit()

print("Done")

【问题讨论】:

  • 没有mysqlite这样的东西。有mysql,有sqlite。
  • “它停止工作”:完全正确你在这里是什么意思?应用程序是否挂起(即它似乎不再响应)。你有例外吗?如果是这样,请编辑问题以包含异常的完整回溯,因为您的问题的修复可能取决于您得到的异常。还是发生了其他事情,如果发生了,究竟是什么?我们还不能帮助您,因为我们没有足够的详细信息。
  • 谢谢,@LukeWoodward。它在 CSV 数据的第一行正确运行脚本、创建 URL、将查询发送到 API、接收 JSON、分配预期变量并将它们插入表中,但随后不运行其余行来自 CSV。当我注释掉最后的 cur.execute 行时,它成功地遍历了 CSV 的所有 50 行,并为每个查询接收了预期的 JSON 数据。我想不通。

标签: python json sqlite loops


【解决方案1】:

程序在这里改变光标的“值”

cur.execute('''INSERT INTO Omdbdump.......)

在此处迭代光标时for row in fh:

可能的解决方案:

  • 为插入创建另一个光标
  • 使用连接的执行方法进行插入。

【讨论】:

  • 谢谢你,DinoCoderSaurus,太好了:在该行中将 cur.execute 更改为 conn.execute 有效。
【解决方案2】:

接受的答案是 [DinoCoderSaurus][1] 的一个很好的解释,它帮助我回答了我自己的 [问题][2],但 connection.execute() 的建议在 apsw 中不起作用。在使用元组列表链接两个循环之后,我必须连接一些 sql 并将一些调用放入一个新循环中。

对 OP 案例的答案将是改变:

    cur.execute('''INSERT INTO Omdbdump (title, year, rated, released, runtime, genre, director, writer, actors, plotlong, language, country, awards, poster, imdbrating, rtrating, mcrating, imdbid, type, dvd, boxoffice, production, website) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )''', (title, year, rated, released, runtime, genre, director, writer, actors, plotlong, language, country, awards, poster, imdbrating, rtrating, mcrating, imdbid, type, dvd, boxoffice, production, website) )

到:

values=[] #outside the original loop

#then inside the loop    
    values.append((title, year, rated, released, runtime, genre, director, writer, actors, plotlong, language, country, awards, poster, imdbrating, rtrating, mcrating, imdbid, type, dvd, boxoffice, production, website))

#then after the values harvesting loop has closed a new loop:
for value in values:
    cur.execute('''INSERT INTO Omdbdump (title, year, rated, released, runtime, genre, director, writer, actors, plotlong, language, country, awards, poster, imdbrating, rtrating, mcrating, imdbid, type, dvd, boxoffice, production, website) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )''', value)


  [1]: https://stackoverflow.com/users/5577076/dinocodersaurus
  [2]: https://stackoverflow.com/questions/69706486/why-does-apsw-cursor-executesql-vars-break-outer-for-loop/69712751#69712751

【讨论】:

  • 谢谢,安迪,这听起来是一种更强大的方法,但是当我尝试这样做时,同一行(来自值中的最后一条记录)被插入到表的每一行中。我得到 49 条相同的线。我可以在值列表中看到所有标题的数据,但不知道为什么插入循环没有遍历整个值列表
  • 您是否尝试过在 cur.execute 语句之前打印值?它应该是正确的。需要查明错误
猜你喜欢
  • 2016-11-26
  • 2016-08-18
  • 1970-01-01
  • 2019-01-11
  • 2020-03-25
相关资源
最近更新 更多