我可以在SQLite的值列表中使用if语句吗?

2024-05-15 23:24:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我想写一段代码,从SQLite数据库导入文件,然后检查是否已经有一条记录具有一些相同的属性,在这种情况下,我不想运行if语句的部分

        for entry in entries:
            if beer.name not in entries[3]:
                print(f'New beer found: {beer.name}')
                print(f'Beer price: {beer.price}')
                beer.rating, beer.unt_id, beer.style = untappd_scraper(beer)
                if beer.unt_id is not entry[4]:
                    if site == "Hopt":
                        c.execute("INSERT INTO beers VALUES (:a, :b, :c, :g, :e, :f)", {'a': beer.name, 'b': beer.style, 'c': beer.rating,'g': beer.unt_id, 'e': beer.price, 'f': ''})
                        # conn.commit()
                    elif site == "Beerdome":
                        c.execute(
                            "INSERT INTO beers VALUES (:a, :b, :c, :g, :e, :f)", {'a': beer.name, 'b': beer.style, 'c': beer.rating, 'g': beer.unt_id, 'e': '', 'f': beer.price})
                        # conn.commit()
                conn.commit()

这似乎不起作用,因为啤酒只是不断添加,即使它已经在列表中多次出现。 那么,我如何才能更改此代码以使其正常工作呢


Tags: 代码nameinidifstylenotconn
1条回答
网友
1楼 · 发布于 2024-05-15 23:24:15

问题中的代码看起来像是查询了数据库表,现在正在检查每一行是否与啤酒的详细信息匹配。除了拼写错误,这不太可能起作用,因为如果任何行与啤酒不匹配,将插入新的啤酒行

假设表格看起来有点像这样:

CREATE TABLE beers (
    id INTEGER PRIMARY KEY,
    name TEXT,
    unt_id INTEGER)

我们可以获取啤酒的详细信息,然后查询是否有匹配的行,如果没有找到行,则插入,如下所示:

# Let's assume we have got a beer name AND unt_id.
name, unt_id = some_function_that_gets_beer_details()

cur.execute("""SELECT COUNT(1) FROM beers WHERE name = ? AND unt_id = ?""", (name, unt_id))
count, = cur.fetchone()
if count == 0:
    # Beer not found, do insert
    cur.execute("""INSERT INTO beers (name, unt_id) VALUES (?, ?)""", (name, unt_id))
    conn.commit()

这工作得很好,但如果有多个人在运行该程序,则可以通过在查询和插入之间插入来添加重复的啤酒(这称为竞争条件)。我们可以通过向表中添加约束来防止这种情况,要求nameunt_id的组合是唯一的。表的DDL如下所示:

CREATE TABLE beers (
    id INTEGER PRIMARY KEY,
    name TEXT,
    unt_id INTEGER,
    CONSTRAINT uniq_name_unt UNIQUE (name, unt_id))

或者可以使用以下SQL更新现有表:

CREATE UNIQUE INDEX uniq_name_unt ON beers (name, unt_id)

现在代码无需检查即可插入数据,因此不再存在竞争条件。但是,如果啤酒已经存在于表中,代码必须处理发生的错误

try:
    cur.execute("""INSERT INTO beers (name, unt_id) VALUES (?, ?)""", ('IPA', 1))
    conn.commit()
except sqlite3.IntegrityError: 
    conn.rollback()
    print(f'Beer {name}-{unt_id} already exists!')

相关问题 更多 >