如何用Python将一个CSV导入到两个不同的SQL表中,并相互引用。

目标

我正在做CS50 Web的项目1,书籍(https:/docs.cs50.netocwwebprojects1project1.html。). 它要求我将一个csv导入到一个有一两个表的数据库中。这个csv看起来是这样的。

isbn, title, author, year
0131320931, The Hobbit, J.R.R. Tolkien, 1937

我选择了两张表: 书籍和作者。它们看起来是这样的。

CREATE TABLE books (book_id SERIAL PRIMARY KEY, isbn VARCHAR(13), title VARCHAR(26021), author references authors(author_id),  year INT);
CREATE TABLE authors (author_id SERIAL PRIMARY KEY, name VARCHAR(255));

我的目标是使用Python脚本和SQLAlchemy将CSV导入到这两个表中。

问题

我的问题是在导入CSV时,书籍中的国外id引用作者。我目前的代码是这样的。

def main():
    f = open("books.csv")
    reader = csv.reader(f)
    for isbn, title, author, year in reader:
        db.execute("INSERT INTO authors (name) VALUES(:author)",
                   {"author": author})
        db.execute("INSERT INTO books (isbn, title, year) VALUES(:isbn, :title, :year)", {
                   "isbn": isbn,
                   "title": title
                   "year": year})
    db.commit()

结果是:

 book_id |    isbn    |         title         | author | year 
---------+------------+-----------------------+--------+------
       1 | 0380795272 | Krondor: The Betrayal |   *    | 1998
       2 | 1416949658 | The Dark Is Rising    |        | 1973
*Should be "1", the foreign key for Raymond E. Feist.
 author_id |       name       
-----------+------------------
         1 | Raymond E. Feist
         2 | Susan Cooper

我似乎不知道该如何同时导入它们 并生成作者的外键。我想过创建一个临时表,然后使用SELECT WHERE查询,但这似乎是一个逃避。我还试过在第二个INSERT中使用作者的书籍中使用嵌套函数,但似乎并不奏效。

我使用的是PostgreSQL。

任何帮助都是感激的,以及对我提出问题的反馈!

谢谢你的帮助

解决方案:

解决办法

我是能够弄明白的。我使用了PostgreSQL的 ON CONFLICT DO NOTHING 后的条款 authors.name 列是唯一的。有一个注意事项,在这个数据结构中我认为是不可避免的,那就是作者名字相同。我也不知道如何包含由多个作者撰写的书籍。

代码

def main():
    f = open("books.csv")
    reader = csv.reader(f)
    reader.__next__
    for isbn, title, author, year in reader:
        db.execute("INSERT INTO authors (name) VALUES(:author) ON CONFLICT (name) DO NOTHING",
                   {"author": author})
        db.execute("INSERT INTO books (isbn, title, author, year) VALUES(:isbn, :title, (SELECT author_id FROM authors WHERE name = :author), :year)", {
                   "isbn": isbn,
                   "author": author,
                   "title": title,
                   "year": year})
    db.commit()

产量

 author_id |       name       
-----------+------------------
        38 | Raymond E. Feist
 book_id |    isbn    |         title         | author | year 
---------+------------+-----------------------+--------+------
      38 | 0380795272 | Krondor: The Betrayal |     38 | 1998

注:因为它们是第一批输入的记录,所以它们有相同的ID,这是偶然的。

给TA打赏
共{{data.count}}人
人已打赏
解决方案

为什么我在Python文件"<stdin> "中得到这个错误,第2行 n new_squares.append(squares[i]) n ^ IndentationError: expected an indented block?

2022-5-13 22:00:26

解决方案

搜索和添加元素到一个ArrayList的Array中

2022-5-13 22:00:30

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索