使用sqlite3存储奥斯卡金像奖提名信息2

在上一步骤的基础上,使用sqlite3创建以下几个表:

  • ceremonies 存储举行时间和地点
  • movies
  • actors
  • movies_actors 用于存储movies和actors间的多对多关系

重点内容:

  • 数据库的链接/表的创建
  • commit()
  • sqlite的特性,死锁概念及原因
1.创建ceremonies

链接数据库

import sqlite3

conn=sqlite3.connect('./data/nominations.db')
schema=conn.execute("pragma table_info(nominations);").fetchall()
first_ten=conn.execute("select * from nominations limit 10; ")
for row in schema:
    print(row)
for row in first_ten:
    print(row)
(0, 'Year', 'INTEGER', 0, None, 0)
(1, 'Category', 'TEXT', 0, None, 0)
(2, 'Nominee', 'TEXT', 0, None, 0)
(3, 'Won', 'INTEGER', 0, None, 0)
(4, 'Movie', 'TEXT', 0, None, 0)
(5, 'Character', 'TEXT', 0, None, 0)
(2010, 'Actor -- Leading Role', 'Javier Bardem', 0, 'Biutiful ', 'Uxbal')
(2010, 'Actor -- Leading Role', 'Jeff Bridges', 0, 'True Grit ', 'Rooster Cogburn')
(2010, 'Actor -- Leading Role', 'Jesse Eisenberg', 0, 'The Social Network ', 'Mark Zuckerberg')
(2010, 'Actor -- Leading Role', 'Colin Firth', 1, "The King's Speech ", 'King George VI')
(2010, 'Actor -- Leading Role', 'James Franco', 0, '127 Hours ', 'Aron Ralston')
(2010, 'Actor -- Supporting Role', 'Christian Bale', 1, 'The Fighter ', 'Dicky Eklund')
(2010, 'Actor -- Supporting Role', 'John Hawkes', 0, "Winter's Bone ", 'Teardrop')
(2010, 'Actor -- Supporting Role', 'Jeremy Renner', 0, 'The Town ', 'James Coughlin')
(2010, 'Actor -- Supporting Role', 'Mark Ruffalo', 0, 'The Kids Are All Right ', 'Paul')
(2010, 'Actor -- Supporting Role', 'Geoffrey Rush', 0, "The King's Speech ", 'Lionel Logue')

创建表并插入数据:

conn.execute('''create table ceremonies(
             id integer primary key,
             Year integer,
             Host text
            );''')
years_hosts= [(2010, "Steve Martin"),
               (2009, "Hugh Jackman"),
               (2008, "Jon Stewart"),
               (2007, "Ellen DeGeneres"),
               (2006, "Jon Stewart"),
               (2005, "Chris Rock"),
               (2004, "Billy Crystal"),
               (2003, "Steve Martin"),
               (2002, "Whoopi Goldberg"),
               (2001, "Steve Martin"),
               (2000, "Billy Crystal")
            ]

#主键不用指定,系统自动设置
conn.execute("pragma foreign_keys=ON;")#每次插入操作前建议设置,防止插入不含外键的非法数据
conn.executemany("insert into ceremonies(Year,Host) values(?,?);",years_hosts)

conn.commit()#注意:每次执行修改操作应提交,close不会自动调用commit,直接关闭数据库会导致修改丢失

result=conn.execute('select * from ceremonies;').fetchall()
print(result)

返回一个由tuple组成的list:

 [(1, 2010, 'Steve Martin'), 
(2, 2009, 'Hugh Jackman'), (3, 2008, 'Jon Stewart'), 
(4, 2007, 'Ellen DeGeneres'), (5, 2006, 'Jon Stewart'), 
(6, 2005, 'Chris Rock'), (7, 2004, 'Billy Crystal'),
 (8, 2003, 'Steve Martin'), (9, 2002, 'Whoopi Goldberg'), 
(10, 2001, 'Steve Martin'), (11, 2000, 'Billy Crystal')]
2. nominations表

nominations中year列已经存在于ceremonies表中了,即冗余列,应该删除;而sqlite为保持轻量级,不允许对表结构进行修改,所以想删除某列只能通过新建的方式。

conn.execute('''create table nominations_two(
                id integer primary key,
                category text,
                nominee text,
                movie text,
                character text,
                won integer,
                ceremonies_id integer,
                foreign key(ceremonies_id) references ceremonies(id)
                );''')

useful_data=conn.execute('''select nominations.category, nominations.nominee, nominations.movie, nominations.character, nominations.won, ceremonies.id
                from nominations
                inner join ceremonies
                on nominations.year==ceremonies.year;
                ''').fetchall()
conn.executemany("insert into nominations_two(category,nominee,movie,character,won,ceremonies_id) values(?,?,?,?,?,?)",useful_data)
print(conn.execute("select * from nominations_two limit 10;").fetchall())

conn.execute('DROP table nominations;')
conn.execute('alter table nominations_two rename to nominations;')
3.创建movies/actors/movies_actors表

创建表

conn.execute("create table movies(id integer primary key,movie text);")
conn.execute("create table actors(id integer primary key,actor text);")
conn.execute('''create table movies_actors(
                id integer primary key,
                movie_id integer references movies(id),
                actor_id integer references actors(id));
                ''')

插入数据

conn.execute("insert into movies(Movie) select distinct movie from nominations;")#字段不区分大小写
conn.execute("insert into actors(Actor) select distinct Nominee from nominations;")

movie_actor_pair=conn.execute("select distinct movie,Nominee from nominations;").fetchall()
conn.executemany('''insert into movies_actors(movie_id,actor_id) 
                values((select id from movies where movie==?),(select id from actors where actor==?));'''
                ,movie_actor_pair)

conn.commit()
conn.close()

创建完成,此时我们可以通过终端或者可视化工具查看创建结果:

使用sqlite3存储奥斯卡金像奖提名信息2_第1张图片

你可能感兴趣的:(使用sqlite3存储奥斯卡金像奖提名信息2)