如何插入关系表?

时间:2017-05-28 09:19:44

标签: python mysql

我有一个关系数据库,我正在尝试学习如何插入行。这就是我所拥有的:

artist {id, name}
genre  {id, name}
album  {id, name, artist_id, genre_id}
track  {id, album_id, track_name}

我最大的问题是,我希望artist是唯一的,因此不能有名字相同的艺术家,但我尝试的每个查询都会插入重复项。我尝试将桌子改成独一无二的,但我发现不可能由一位艺术家添加多首曲目。在这一点上,我被困住了;我没有成功地查看了ON DUPLICATE语句,甚至尝试在我的脚本中检测重复项并从那里运行不同的插入。

感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:0)

根据您的数据库设计,它应该可以正常工作。我很遗憾所有ids对于他们各自的表都是primary key。同时为艺术家姓名提供约束UNIQUE。如果您使用脚本创建表,请确保在输入后提交。现在,您可以插入已存在的名称。也做外键。这个示例代码适用于python3中的sqlite。

import sqlite3 as sql
a = sql.connect('test_db')
conn = a.cursor()

query = 'create table artists(id INTEGER primary key AUTOINCREMENT, artist_name varchar(30) unique)'
conn.execute(query)
query2 = 'create table albums(id INTEGER primary key AUTOINCREMENT, artist_id integer, foreign key(artist_id) references artists(id))'
conn.execute(query2)
query3 = 'create table tracks(id INTEGER primary key AUTOINCREMENT, album_name varchar(30), album_id integer, foreign key(album_id) references albums(id))'
conn.execute(query3)

conn.execute('insert into artists(artist_name) values("john")')
conn.execute('insert into artists(artist_name) values("Doe")')
conn.execute('insert into albums(artist_id) values(1)')
conn.execute('insert into albums(artist_id) values(2)')
conn.execute('insert into tracks(album_name, album_id) values("something",1)')
conn.execute('insert into tracks(album_name, album_id) values("someotherthing",2)')

a.commit()

希望这会有所帮助:)

答案 1 :(得分:0)

为什么要依靠数据库的结构来防止重复? 加载数据时很容易做到这一点 以下是使用sqlite3,可能需要改进:

数据文件catalog.txt:

album 1,artist 1,rock,track 1
album 1,artist 1,rock,track 2
album 1,artist 1,rock,track 3
album 1,artist 1,rock,track 4
album 1,artist 1,rock,track 5
album 1,artist 1,rock,track 6
album 1,artist 1,rock,track 7
album 1,artist 1,rock,track 8
album 1,artist 1,rock,track 9
album 1,artist 1,rock,track 10
album 2,artist 1,rock,track 1
album 2,artist 1,rock,track 2
album 2,artist 1,rock,track 3
album 2,artist 1,rock,track 4
album 2,artist 1,rock,track 5
album 3,artist 2,regge,track 1
album 3,artist 2,regge,track 2
album 3,artist 2,regge,track 3
album 2,artist 3,rock,track 1
album 2,artist 3,rock,track 2
album 2,artist 3,rock,track 3
album 2,artist 3,rock,track 4
album 2,artist 3,rock,track 5

代码:
如果艺术家不同,这确实允许重复的专辑名称 插入新记录时,它依赖于autoincrement

import sqlite3
db_name = "catalog.db"
db = sqlite3.connect(db_name, isolation_level=None)
db.row_factory = sqlite3.Row
cursor = db.cursor()
result = cursor.execute("create table if not exists artist (artist_id integer primary key autoincrement,artist_name char(150))")
result = cursor.execute("create table if not exists genre (genre_id integer primary key autoincrement,genre_name char(150))")
result = cursor.execute("create table if not exists album (album_id integer primary key autoincrement,album_name char(150),artist_id int,genre_id int)")
result = cursor.execute("create table if not exists track (track_id integer primary key autoincrement,track_name char(150),album_id int)")

with open('catalog.txt','r') as f:
    data = f.readlines()

for i in data:
    track = i.split(',')
    alb = track[0].strip()
    art = track[1].strip()
    gen = track[2].strip()
    tra = track[3].strip()

    #Check for existing artist
    cursor.execute("select artist_id from artist where artist_name = ?",[art])
    data = cursor.fetchone()
    if data:
        art_id = data['artist_id']
    else: #Insert new record then record the new id
        db.execute("insert into artist(artist_name) values (?)",(art,))
        cursor.execute("select artist_id from artist where artist_name = ?",[art])
        data = cursor.fetchone()
        art_id = data['artist_id']
        print "Adding artist", art

    #Check for existing genre
    cursor.execute("select genre_id from genre where genre_name = ?",[gen])
    data = cursor.fetchone()
    if data:
        gen_id = data['genre_id']
    else: #Insert new record then record the new id
        db.execute("insert into genre(genre_name) values (?)",(gen,))
        cursor.execute("select genre_id from genre where genre_name = ?",[gen])
        data = cursor.fetchone()
        gen_id = data['genre_id']
        print "  Adding genre", gen

    #Check for existing album by given artist
    cursor.execute("select album_id from album where album_name = ? and artist_id = ?",[alb,art_id])
    data = cursor.fetchone()
    if data:
        alb_id = data['album_id']
    else: #Insert new record then record the new id
        db.execute("insert into album(album_name,artist_id,genre_id) values (?,?,?)",(alb,art_id,gen_id,))
        cursor.execute("select album_id from album where album_name = ? and artist_id = ?",[alb,art_id])
        data = cursor.fetchone()
        alb_id = int(data[0])
        print "    Adding album", alb

    #Check for track in given album
    cursor.execute("select track_id from track where album_id = ? and track_name = ?",[alb_id,tra])
    data = cursor.fetchone()
    if data:
        pass # duplicate"
    else:
        db.execute("insert into track(track_name,album_id) values (?,?)",(tra,alb_id,))
        print "      Adding", tra, art, alb

答案 2 :(得分:-1)

您如何访问数据库?你使用的是任何形式的ORM吗?

通常,您不能为每个曲目再次插入艺术家。

因此,在插入相册时,如果艺术家已经存在,您应该查找您的表格。如果它存在,则获取它的id并在插入轨道时重复使用它。如果艺术家尚未存在,请插入并保存artist_id以迭代曲目列表并使用artist_id插入每个曲目。