計算機科学のブログ

SQL - SQLite - Python - 複数テーブルのデータベース設計 - 現行テーブルからの脱却 - 列, 分割, 文字列

Head First SQL ―頭とからだで覚えるSQLの基本Lynn Beighley(著)、 佐藤 直生(監訳)、 松永 多苗子(翻訳)、 オライリージャパンの 7章(複数テーブルのデータベース設計 - 現行テーブルからの脱却)、p.290(自分で考えてみよう)の解答を求めてみる。

schema4.sql

alter table my_contacts rename to temp;
create table my_contacts(
    contact_id integer primary key autoincrement,
    last_name text,
    first_name text,
    phone text,
    email text,
    gender text,
    birth_day date,
    profession text,
    city text,
    state text,
    status text,
    interest1 text,
    interest2 text,
    interest3 text,
    interest4 text,
    seeking text
);

コード

sample4.py

#! /usr/bin/env python3
import sqlite3

con = sqlite3.connect('sample.db')
con.row_factory = sqlite3.Row
cur = con.cursor()


def p(cur: sqlite3.Cursor, table: str):
    cur.execute(
        f"""
select * from {table}
"""
    )
    # if (d := cur.description) is not None:
    #     print([t[0] for t in d])
    for row in cur.fetchall():
        print(dict(row))


p(cur, 'my_contacts')

with open(f'schema4.sql') as f:
    cur.executescript(f.read())
con.commit()

_sql = """
select * from temp
"""
cur.execute(_sql)
rows = cur.fetchall()

_sql = """
insert into my_contacts(
    last_name,
    first_name,
    phone,
    email,
    gender,
    birth_day,
    profession,
    city,
    state,
    status,
    interest1,
    interest2,
    interest3,
    interest4,
    seeking
) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
"""


def get_interest(interests: list, i: int, l: int):
    if i < l:
        return interests[i]
    return None


for row in rows:
    interests = row['interests'].split('、')
    l = len(interests)
    interest1 = get_interest(interests, 0, l)
    interest2 = get_interest(interests, 1, l)
    interest3 = get_interest(interests, 2, l)
    interest4 = get_interest(interests, 3, l)
    cur.execute(
        _sql,
        (
            row['last_name'],
            row['first_name'],
            row['tel'],
            row['email'],
            row['gender'],
            row['birthday'],
            row['profession'],
            row['city'],
            row['state'],
            row['status'],
            interest1,
            interest2,
            interest3,
            interest4,
            row['seeking'],
        ),
    )
_sql = """
drop table temp
"""
cur.execute(_sql)
con.commit()

p(cur, 'my_contacts')

cur.close()
con.close()

入出力結果(Terminal, Zsh)

% ./sample4.py     
{'email': 'jill_anderson@breaknechpizza.com', 'birthday': '1980-09-05', 'first_name': 'ジリアン', 'last_name': 'アンダーソン', 'interests': 'カヤック乗り、爬虫類', 'seeking': '恋人、友達', 'status': '独身', 'profession': 'テクニカルライター', 'location': 'カリフォルニア州パロアルト', 'gender': 'F', 'tel': None, 'city': None, 'state': None}
{'contact_id': 1, 'last_name': 'アンダーソン', 'first_name': 'ジリアン', 'phone': None, 'email': 'jill_anderson@breaknechpizza.com', 'gender': 'F', 'birth_day': '1980-09-05', 'profession': 'テクニカルライター', 'city': None, 'state': None, 'status': '独身', 'interest1': 'カヤック乗り', 'interest2': '爬虫類', 'interest3': None, 'interest4': None, 'seeking': '恋人、友達'}
%