Python中SQLite3关联两表查询打印结果异常问题求助
排查SQLite3关联查询异常的问题
嘿,我来帮你梳理下这个关联查询的问题~首先先还原你的场景,然后一步步找出可能的问题点,再给出解决方案。
先补全你的代码场景
我先把你没写完的代码补全,方便排查问题:
import sqlite3 # 连接数据库 conn = sqlite3.connect("Alchemy_Data_Bank.db") cursor = conn.cursor() # 开启外键约束(SQLite默认关闭,这一步很重要!) cursor.execute("PRAGMA foreign_keys = ON") # 创建配料表 cursor.execute("""CREATE TABLE IF NOT EXISTS Ingredients ( ingredient_id INTEGER PRIMARY KEY, ingredient_name TEXT NOT NULL )""") # 创建食谱表,包含三个配料ID字段 cursor.execute("""CREATE TABLE IF NOT EXISTS Recipies ( recipe_id INTEGER PRIMARY KEY, recipe_name TEXT NOT NULL, ingred1 INTEGER, ingred2 INTEGER, ingred3 INTEGER, -- 设置外键关联配料表 FOREIGN KEY(ingred1) REFERENCES Ingredients(ingredient_id), FOREIGN KEY(ingred2) REFERENCES Ingredients(ingredient_id), FOREIGN KEY(ingred3) REFERENCES Ingredients(ingredient_id) )""") # 你的数据列表 idata = [(0,"Ingredient1"), (1,"Ingredient2")] rdata = [(0,"Recipie1",0,1,1)] # 插入数据 cursor.executemany("INSERT INTO Ingredients VALUES (?, ?)", idata) cursor.executemany("INSERT INTO Recipies VALUES (?, ?, ?, ?, ?)", rdata) # 一定要提交事务!否则数据不会写入数据库 conn.commit()
可能导致关联查询异常的原因&解决方案
你说关联查询时出现异常,大概率是下面几个问题之一:
1. 忘记提交事务
很多人会忽略conn.commit()这一步,插入数据后如果不提交,数据只是存在内存的临时事务里,数据库里并没有真正写入,查询时自然找不到数据,会抛出类似查询结果为空或no such row的异常。
2. 关联查询的写法错误
因为你的食谱表有三个配料ID字段,需要分别和配料表关联三次,给每个配料表起不同的别名,否则只能获取到一个配料的信息,甚至会出现笛卡尔积或者字段不匹配的异常。
正确的关联查询写法应该是这样:
# 执行关联查询,获取食谱和对应的三个配料名称 cursor.execute(""" SELECT r.recipe_name, i1.ingredient_name AS 配料1, i2.ingredient_name AS 配料2, i3.ingredient_name AS 配料3 FROM Recipies r -- 用LEFT JOIN避免某个配料ID为空时查询不到整条数据 LEFT JOIN Ingredients i1 ON r.ingred1 = i1.ingredient_id LEFT JOIN Ingredients i2 ON r.ingred2 = i2.ingredient_id LEFT JOIN Ingredients i3 ON r.ingred3 = i3.ingredient_id """) # 打印查询结果 results = cursor.fetchall() for row in results: print(f"食谱名称: {row[0]}") print(f"所用配料: {row[1]}, {row[2]}, {row[3]}") # 最后别忘了关闭连接 conn.close()
3. 表结构或字段名拼写错误
比如创建表时把Recipies写成Recipe,或者把ingredient_id写成id,查询时用了错误的字段名,就会抛出no such column或者no such table的异常。一定要确保表名、字段名和查询语句里的完全一致。
4. 外键约束未开启
SQLite默认是关闭外键约束的,如果你插入了不存在的配料ID,不会报错,但关联查询时会出现关联不上的情况。所以一定要在连接后执行cursor.execute("PRAGMA foreign_keys = ON")开启外键约束,这样插入不符合外键的数据时会直接抛出异常,方便你排查数据问题。
运行完整代码后的预期结果
食谱名称: Recipie1 所用配料: Ingredient1, Ingredient2, Ingredient2
内容的提问来源于stack exchange,提问作者Cazo0
相关产品推荐
相关产品推荐

