Chapter16 Data Models and Relational SQL&Assignment

本文介绍了一种使用Python从XML文件中解析音乐元数据并将其导入SQLite数据库的方法。通过创建必要的表结构,并利用XML的特性来提取数据,最终实现了音乐库的有效管理和查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下:

import xml.etree.ElementTree as ET
import sqlite3

conn = sqlite3.connect('trackdb.sqlite')
cur = conn.cursor()

# Make some fresh tables using executescript()
cur.executescript('''

DROP TABLE IF EXISTS Artist;
DROP TABLE IF EXISTS Album;
DROP TABLE IF EXISTS Track;
DROP TABLE IF EXISTS GENRE;

CREATE TABLE Artist (
    id  INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    name    TEXT UNIQUE
);

CREATE TABLE Genre (
    id  INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    name    TEXT UNIQUE
);

CREATE TABLE Album (
    id  INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    artist_id  INTEGER,
    title   TEXT UNIQUE
);

CREATE TABLE Track (
    id  INTEGER NOT NULL PRIMARY KEY 
        AUTOINCREMENT UNIQUE,
    title TEXT  UNIQUE,
    album_id  INTEGER,
    genre_id  INTEGER,
    len INTEGER, rating INTEGER, count INTEGER
);
''')
#关于primaryID的设置:NOT NULL:不为空;AUTOINCREMENT:主键自动增加编号(必须设置主键)


fname = raw_input('Enter file name: ')
if ( len(fname) < 1 ) : fname = 'Library.xml'

# <key>Track ID</key><integer>369</integer>
# <key>Name</key><string>Another One Bites The Dust</string>
# <key>Artist</key><string>Queen</string>
# xml中的格式,lookup方法就是通过传入的参数key,返回对应text。


def lookup(d, key):
    found = False
    for child in d:
        if found : return child.text
        if child.tag == 'key' and child.text == key :
            found = True
    return None

stuff = ET.parse(fname)
all = stuff.findall('dict/dict/dict')
print 'Dict count:', len(all)
for entry in all:
    if ( lookup(entry, 'Track ID') is None ) : continue

    name = lookup(entry, 'Name')
    artist = lookup(entry, 'Artist')
    album = lookup(entry, 'Album')
    count = lookup(entry, 'Play Count')
    rating = lookup(entry, 'Rating')
    length = lookup(entry, 'Total Time')
    genre=lookup(entry,'Genre')

    if name is None or artist is None or album is None or genre is None : 
        continue

    print name, artist, album, count, rating, length,genre

    cur.execute('''INSERT OR IGNORE INTO Artist (name) 
        VALUES ( ? )''', ( artist, ) )
    cur.execute('SELECT id FROM Artist WHERE name = ? ', (artist, ))
    artist_id = cur.fetchone()[0]

    cur.execute('''INSERT OR IGNORE INTO Album (title, artist_id) 
        VALUES ( ?, ? )''', ( album, artist_id ) )
    cur.execute('SELECT id FROM Album WHERE title = ? ', (album, ))
    album_id = cur.fetchone()[0]

    cur.execute('''INSERT OR IGNORE INTO Genre(name) VALUES (?)''',(genre, ))
    #INSERT OR IGNORE:当有重复记录时忽略,返回值为0
    cur.execute('SELECT id FROM Genre WHERE name=?',(genre, ))
    genre_id=cur.fetchone()[0]

    cur.execute('''INSERT OR REPLACE INTO Track
        (title, album_id,genre_id,len, rating, count) 
        VALUES ( ?, ?, ?, ?, ? ,?)''', 
        ( name, album_id, genre_id,length, rating, count ) )

    conn.commit()

最后在SQL执行下列语句:

SELECT Track.title, Artist.name, Album.title, Genre.name 
    FROM Track JOIN Genre JOIN Album JOIN Artist 
    ON Track.genre_id = Genre.ID and Track.album_id = Album.id 
        AND Album.artist_id = Artist.id
    ORDER BY Artist.name LIMIT 3

通过primary key和foreign key把每个表之间联系起来,最后按照artist.name输出前三个。
结果:
这里写图片描述

Assignment for Chapter 3 作业内容: Q1. Consider the following bank database, where the primary keys are underlined, construct the following SQL queries for this relational database. branch(branch_name, branch_city, assets) customer (customer name, customer_street, customer_city) loan (loan number, branch_name, amount) borrower (customer name, loan number) account (account number, branch_name, balance ) depositor (customer name, account_number) a. Find all customers who have an account at all the branches located in “Brooklyn”. b. Find out the total sum of all loan amounts in the bank. c. Find the names of all branches that have assets greater than those of at least one branch located in “Brooklyn”. Q2. Consider the following database, where the primary keys are underlined, construct the following SQL queries for this relational database. employee (employee_name, street, city) works (employee_name, company_name, salary) company (company_name, city) manages (employee_name, manager_name) a. Find the names of all employees who work for First Bank Corporation. b. Find all employees in the database who live in the same cities as the companies for which they work. c. Find all employees in the database who live in the same cities and on the same streets as do their managers. d. Find all employees who earn more than the average salary of all employees of their company. e. Find the company that has the smallest payroll. Q3. Consider the following database, where the primary keys are underlined, construct the following SQL queries for this relational database. member(memb no, name, age) book(isbn, title, authors, publisher) borrowed(memb no, isbn, date) a. Print the names ofmemberswho have borrowed any book published by “McGraw-Hill”. b. Print the names ofmemberswho have borrowed all books published by “McGraw-Hill”. c. For each publisher, print the names ofmemberswho have borrowed more than five books of that publisher. d. Print the average number of books borrowed permember. Take into account that if an member does not borrow any books, then that member does not appear in the borrowed relation at all.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值