【问题标题】:Try/Except not working when fetching from SQLite database从 SQLite 数据库中获取时尝试/排除不工作
【发布时间】:2019-04-29 23:48:46
【问题描述】:

我正在构建一个从 iTunes 库导出中的 XML 文件中提取不同属性的应用程序。由于并非每首歌曲都有一个流派,因此为每首歌曲找到一个并不总是有效。当程序将流派插入“流派”时,它会自动创建一个 id

CREATE TABLE Genre (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    name TEXT UNIQUE
);

问题是,当 XML 文件中没有找到“流派”时,不会插入任何内容,这意味着我以后无法获取通过添加某些内容创建的 id 以将其放入 tabke 以进行关系查询。为了阻止这种情况,我将插入和提取放在一个 try/except 中,它会捕获

TypeError: 'NoneType' object is not subscriptable

无法执行时出错

cur.fetchone()[0]

。在除了我将流派设置为“无流派”之外,为没有找到流派的情况生成唯一的 id。即使它在 try 块中捕获了异常,它也没有运行。错误:

TypeError                                 Traceback (most recent call last)
~\Documents\python\tracks.py in <module>
     83         cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
---> 84         genre_id = cur.fetchone()[0]
     85     except:

TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
~\Documents\python\tracks.py in <module>
     87         cur.execute('''INSERT OR IGNORE INTO Genre (name) VALUES ( ? )''', ( genre, ) )
     88         cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
---> 89         genre_id = cur.fetchone()[0]
     90 
     91 

TypeError: 'NoneType' object is not subscriptable 

帮助!为什么 try/except 不起作用?

    try:
        cur.execute('''INSERT OR IGNORE INTO Genre (name) VALUES ( ? )''', ( genre, ) )
        cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
        genre_id = cur.fetchone()[0]
    except:
        genre = "No Genre"
        cur.execute('''INSERT OR IGNORE INTO Genre (name) VALUES ( ? )''', ( genre, ) )
        cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
        genre_id = cur.fetchone()[0]

【问题讨论】:

  • try...except 是让您的代码尝试上面的内容,除了。如果失败,它将执行except 下的代码。如果您将相同的失败代码放在except 下,它将不起作用。您的异常表明您的代码在第 84 行(在 try 下)和第 89 行(在 except 下)有问题。所以,尝试...除了工作。更大的问题是,为什么会抛出异常。您是否有可能没有您正在寻找的流派的记录?
  • 确实如此。问题更像是为什么除了抛出错误之外。第一次运行时,流派成功添加到数据库,但下一首没有流派的歌曲不起作用。为什么即使定义了流派变量它也不插入?

标签: sql python-3.x sqlite


【解决方案1】:

好的,先解决

import sqlite3
conn = sqlite3.connect('systeminfo.db')
cur = conn.cursor()

genre = 'test'
try:
    cur.execute('''INSERT OR IGNORE INTO Genre (name) VALUES ( ? )''', ( genre, ) )
    cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
    genre_id = cur.fetchone()
    if genre_id is None:
        print('Select did not find any artist for {} genre'.format(genre))
    else:
        print('Select resulted in Artist ID {}'.format(genre_id[0]))
except Exception as e:
    print('Exception: {}'.format(e))
    raise Exception(e)

conn.commit()
conn.close()

看,cur.fetchone() 可能会导致一行,如果没有行,则可能是 None。所以,让我们做一个 if..then 来检查 None。

这就是似乎正在发生的事情。在帖子底部滚动以找到您的答案。

表格

CREATE TABLE Artist (
    id integer not null primary key autoincrement,
    name text,
    genre text
);

CREATE TABLE Genre (
    id integer not null primary key autoincrement,
    name text unique
);

数据

sqlite> select * from Artist;
Run Time: real 0.000 user 0.000086 sys 0.000054
sqlite> select * from Genre;
Run Time: real 0.000 user 0.000092 sys 0.000064
sqlite>

基本上没有数据。

您的代码

import sqlite3
conn = sqlite3.connect('systeminfo.db')
cur = conn.cursor()

genre = 'test'
try:
    cur.execute('''INSERT OR IGNORE INTO Genre (name) VALUES ( ? )''', ( genre, ) )
    cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
    genre_id = cur.fetchone()[0]
except:
    cur.execute('''INSERT OR IGNORE INTO Genre (name) VALUES ( ? )''', ( genre, ) )
    cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
    genre_id = cur.fetchone()[0]

conn.commit()
conn.close()

问题

您的错误发生在两个地方。在您的 try 块中,genre_id = cur.fetchone()[0] 存在错误。一旦遇到错误,控制就转到except 块。在该块中,代码被重复。这意味着,错误重复出现。在该块中,没有错误处理,因为它是错误处理。因此,python 在 except 块中为同一件事引发了另一个错误genre_id = cur.fetchone()[0]。

清理问题

import sqlite3
conn = sqlite3.connect('systeminfo.db')
cur = conn.cursor()

genre = 'test'
try:
    cur.execute('''INSERT OR IGNORE INTO Genre (name) VALUES ( ? )''', ( genre, ) )
    cur.execute('SELECT id FROM Artist WHERE name = ? ', (genre, ))
    genre_id = cur.fetchone()[0]
except Exception as e:
    print('Exception: {}'.format(e))

conn.commit()
conn.close()

好的。在except 中,我们想要处理异常并可能打印出异常。所以,我们将使用except Exception as e。现在,错误信息在e 中。我们打印出来,就是这样。

$ python myfile.py
Exception: 'NoneType' object is not subscriptable

但是如果我想显示错误在哪里呢?

在print('Exception: {}'.format(e)) 正下方添加raise Exception(e)。所以,结果变成了这样:

$ python myfile.py
Exception: 'NoneType' object is not subscriptable
Traceback (most recent call last):
  File "testy.py", line 9, in <module>
    genre_id = cur.fetchone()[0]
TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "testy.py", line 12, in <module>
    raise Exception(e)
Exception: 'NoneType' object is not subscriptable

raise 语句在屏幕上列出了发生问题的位置。

【讨论】:

  • 但是如果我想在 Genre 表中有一个名为“No Genre”的 Genre 以不重复多次重复的 NULL id 怎么办?这是代码:
  • @SalomønC.S.你可以编辑你的帖子并添加你的代码吗?您可以通过cur.execute('insert or ignore into Genre (name) VALUES ( ? )', ( 'No Genre', ) ) 然后cur.execute("update Artists set Genre = 'No Genre' where Genre is null") 轻松做到这一点
猜你喜欢
  • 2012-06-06
  • 2012-08-27
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
相关资源
最近更新 更多