メモ:PythonでDBを使用する②

>>目標の確認
弊社のポータルサイトで使用できる蔵書管理アプリを作りたい。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
今日やること。
PythonGUIアプリで自宅の書籍情報を確認できるようにする。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ひとまずテーブルを作成する。

import sqlite3

#DBに接続
conn=sqlite3.connect("Ouchi.db",isolation_level=None)

#Create Table
sql="""
CREATE TABLE Hondana(
   id VARCHAR(4) primary key,
   name VARCHAR(128),
   author VARCHAR(128)
);
"""
#CREATE TABLEを実行
conn.execute(sql)

考慮点

●テーブルはこんな感じにしようかなと思ったんだけど,IDをどう振ろうかな,と思ってしまった。
私が持っている本はだいたい,ITの本,歴史の本,理科数学の復習系の本,その他,という感じなのでアルファベット1桁+数字連番3桁とかにしようかと思う。
ジャンルごとにアルファベットを振っておけばあとでそこを利用してビューを作成したり出来そうだな,とか思った。

I:IT
H:History
S:Science
L:Liberal Arts
O:Other
こんな感じの分類をした。

●NOT NULL制約を入れようと思ったんだが,今回使ってる本でばばーっと見た感じ入れてるところが見当たらないので一旦やめた。多分あとでALTERで変更できるだろう。
●蔵書管理する場合は貸出日や返却日,返却予定日なんかも必要だけれども,これは別テーブルでいい気がするので後回しに。
管理テーブルを用意してCheckOutDayやReturnDay,DueDay,EmpIDあたりのカラムを用意したらいいんだろう,と目星だけつけておく…。


とりあえず机の上にあった本を適当に登録する

#データ登録
conn.execute("INSERT INTO Hondana VALUES('I001','独習Python入門-1日でプログラミングに強くなる','湯本堅隆')")
conn.execute("INSERT INTO Hondana VALUES('I002','Pythonデータベースプログラミング入門','日向俊二')")
conn.execute("INSERT INTO Hondana VALUES('H001','世界史の新常識','文藝春秋編')")
conn.execute("INSERT INTO Hondana VALUES('L001','1日1ページ読むだけで身につく世界の教養【人物編】','David S.Kidde/Noah D.Oppenheim')")
conn.execute("INSERT INTO Hondana VALUES('I003','ORACLE MASTER Oracle Database 12c Bronze[12c SQL基礎]','西昭彦・飯室美紀・鈴木佐和・岡野友紀・矢島祐子')")
conn.execute("INSERT INTO Hondana VALUES('H002','日本史は逆から学べ近現代史集中講義','河合敦')")
conn.execute("INSERT INTO Hondana VALUES('H003','30の名城から学ぶ日本史','安藤優一郎')")
conn.execute("INSERT INTO Hondana VALUES('S001','元素118の新知識','桜井弘')")


レコードを確認。入っている。
f:id:ci_melon:20190421122001p:plain


表示するだけのGUIができた。
f:id:ci_melon:20190421124749p:plain

改造して,見た目を変えた。
f:id:ci_melon:20190421135653p:plain

#encoding:utf-8
#dispHondana.py
import tkinter
import sqlite3

class MainWindow(tkinter.Frame):

    def __init__(self,parent):
        super(MainWindow,self).__init__(parent)
        self.parent = parent
        self.grid(row=0,column=0)
        #widgets

        self.lblid = tkinter.Label(self,text='ID:',anchor=tkinter.E,width=5)
        self.lbl1 = tkinter.Label(self,text='ID',width=22,anchor =tkinter.W, relief=tkinter.SUNKEN)
        self.lblnm = tkinter.Label(self,text='書籍名:',anchor =tkinter.E,width=5)
        self.lbl2 = tkinter.Label(self,text='書籍名',width=50, anchor =tkinter.W,relief=tkinter.SUNKEN)
        self.lblat = tkinter.Label(self,text='著者名:',anchor=tkinter.E,width=5)
        self.lbl3 = tkinter.Label(self,text='著者名',width=50,anchor =tkinter.W, relief=tkinter.SUNKEN)
        #ボタン
        self.btn = tkinter.Button(self,text='次のレコード', command=self.btn_click)
        #ステータスラベル
        self.lblStatus = tkinter.Label(self,text='',width=22, relief=tkinter.SUNKEN)

        #レイアウト
        self.lblid.grid(row=0,column=0,padx=2,pady=2,sticky=tkinter.E)
        self.lbl1.grid(row=0,column=1,padx=2,pady=2,sticky=tkinter.W)
        self.lblnm.grid(row=1,column=0,padx=2,pady=2,sticky=tkinter.E)
        self.lbl2.grid(row=1,column=1,padx=2,pady=2,sticky=tkinter.W)
        self.lblat.grid(row=2,column=0, padx=2,pady=2, sticky=tkinter.E)
        self.lbl3.grid(row=2,column=1,padx=2,pady=2,sticky=tkinter.W)
        self.btn.grid(row=3,column=0,padx=2,pady=2)

        #initialize
        self.conn = sqlite3.connect("Ouchi.db")
        self.lblStatus.configure(text="Ouchi.dbを開きました")
        self.c=self.conn.execute("SELECT * FROM Hondana")
        self.btn.focus_set()

    def btn_click(self):
        #データの取得
        try:
            row=self.c.fetchone()
        except LookupError:
            self.lblStatus.configure(text="データはありません")
            return
        #ラベルに表示
        if row != None:
            self.lbl1.configure(text=row[0])
            self.lbl2.configure(text=str(row[1]))
            self.lbl3.configure(text=str(row[2]))
        else:
            self.lblStatus.configure(text="データはもうありません")

    def quit(self,event=None):
        self.conn.close()
        self.parent.destroy()

application = tkinter.Tk()
application.title('dispHondana')
window = MainWindow(application)
application.protocol('WM_DELETE_WINDOW',window.quit)
application.mainloop()

配置のポイントはStickyとAnchorにだった。
ラベルの中の文字列のTextAlignはAnchorで指定する

self.lblid = tkinter.Label(self,text='ID:',anchor=tkinter.E,width=5)

ラベル自体のレイアウトの位置はStickyで指定する

self.lbl3.grid(row=2,column=1,padx=2,pady=2,sticky=tkinter.W)

W(左よせ),E(右よせ),N(上よせ),S(下よせ)
方角の頭文字なんだね。
詳細はここに書いてあった。
http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/anchors.htm



とりあえず,今日やると決めてたことは出来た。