我正在使用Python和SQLite来操作数据库。
我在数据库Movies
中有一个SQLite表Data
,如下所示:
| ID | Country
+----------------+-------------
| 1 | USA, Germany, Mexico
| 2 | Brazil, Peru
| 3 | Peru
我在同一个数据库中有一个表Countries
,看起来像这个
| ID | Country
+----------------+-------------
| 1 | USA
| 1 | Germany
| 1 | Mexico
| 2 | Brazil
| 2 | Peru
| 3 | Peru
我想从数据库Data
将所有来自秘鲁的电影插入到一个看起来像这样的新数据库PeruData
| ID | Country
+----------------+-------------
| 2 | Peru
| 3 | Peru
我是SQL新手,无法编写正确的查询。
这是我的尝试:
con = sqlite3.connect("PeruData.db")
cur = con.cursor()
cur.execute("CREATE TABLE Movies (ID, Country);")
cur.execute("ATTACH DATABASE 'Data.db' AS other;")
cur.execute("\
INSERT INTO Movies \
(ID, Country) \
SELECT ID, Country
FROM other.Movies CROSS JOIN other.Countries\
WHERE other.Movies.ID = other.Countries.ID AND other.Countries.Country = 'Peru'\
con.commit()
con.close()
显然,我做错了,因为我收到了错误
sqlite3.OperationalError:没有这样的表:other.Countries
答案 0 :(得分:0)
这是一种成功获得所需结果的解决方法。
您不必编写con = sqlite3.connect("data.db")
然后必须编写con.commit()
和con.close()
,而是可以将代码缩短为以下内容:
with sqlite3.connect("Data.db") as connection:
c = connection.cursor()
这样,您不必每次使用数据库时都提交更改并关闭。这是我学到的一条漂亮的捷径。现在你的代码......
就个人而言,我不熟悉SQL语句 ATTACH DATABASE 。我会将您的新数据库合并到程序的 end 中,这样就可以避免任何您不了解处理的冲突(例如给出的OperationalError)。首先,我将开始获得所需的结果,然后将其插入到新表中。您的第三个执行语句可以像这样重写:
c.execute("""SELECT DISTINCT Movies.ID, Countries.Country
FROM Movies
CROSS JOIN Countries
WHERE Movies.ID = Countries.ID AND Countries.Country = 'Peru'
""")
这可以完成这项工作,但您需要使用 fetchall()将结果集返回到元组列表中,然后可以将其插入到新表中。所以你输入这个:
rows = c.fetchall()
现在,您可以通过创建“PeruData.db”数据库,创建表格以及插入值来打开新连接。
with sqlite3.connect("PeruData.db") as connection:
c = connection.cursor()
c.execute("CREATE TABLE Movies (ID INT, Country TEXT)")
c.executemany("INSERT INTO Movies VALUES(?, ?)", rows)
就是这样。 希望我能回答你的问题!
答案 1 :(得分:0)
当前错误可能是由错字或其他小问题引起的。我可以创建这里描述的数据库,并在修复次要错误后成功执行插入:在行尾添加反斜杠并为所选列添加限定符。
但我也建议你在多表选择中为表使用别名。在我的测试中起作用的代码是:
void getChildren(int pid, levels){
if(levels==0) return Collection.emptyList();
List<ParantCategory> results = al.stream().filter(
p->p.getPid()==pid
).collect(Collectors.toList());
for(ParantCategory p: results){
results.addAll(getChildren(p.getPid(), levels-1));
}
return results;
}