學Python劃重點 六 (數據庫實例編程)

Python 中將數據保存到數據庫中技術有很多,但主要分爲兩類:遵循Python DB-API 規範技術(Python Database API Specification) 和ORM 技術(Object-Relational mapping) 。Python DB-API 規範通過在Python 中編寫SQL 語句訪問數據庫。ORM 技術是面向對象的,對數據的訪問是通過對象實現的,程序員不需要使用SQL 語句。

在Python2.X 中操作MySQL 數據庫可以通過Pyhon 的MySQLdb 模塊實現,由於目前Python3.5 不支持MySQLdb 模塊,所以我們使用pymysql 模塊。


下面介紹數據庫的基本操作步驟:
在這裏插入圖片描述


1. 創建數據庫連接

import pymysql
#連接數據庫
conn = pymysql.connect(
host='localhost',  # 數據庫主機名或IP
port=3306          # 連接數據庫端口號
user='root',       # 訪問數據庫帳號
password='1234',   # 訪問數據庫密碼
database='mydatabase',  # 數據庫中的庫名
charset='utf8')    # 數據庫編碼格式

Connection 對象有一些重要的方法 :
close() :關閉數據庫連接,關閉之後再使用數據庫連接將引發異常。
commit() :提交數據庫事務。
rollback() :回滾數據庫事務。
cursor() :獲得Cursor 遊標對象。

2. 創建遊標

一個Cursor 遊標對象表示一個數據庫遊標,遊標暫時保存了SQL 操作所影響到的數據。
在數據庫事務管理中游標非常重要,遊標是通過數據庫連接創建的,相同數據庫連接創
建的遊標所引起的數據變化,會馬上反映到同一連接中的其他遊標對象。但是不同數據
庫連接中的遊標,是否能及時反映出來,則與數據庫事務管理有關。

遊標Cursor 對象方法:
1.execute(operation[, parameters])
執行一條SQL 語句,operation 是SQL 語句,parameters 是爲SQL 提供的參數,可以是 序列或 字典 類型。返回值是整數,表示執行SQL 語句影響的行數。
2. executemany(operation[, seq_of_params])
執行批量SQL 語句,operation 是SQL 語句,seq_of_params 是爲SQL 提供的參數,
seq_of_params 是 序列 。返回值是整數,表示執行SQL 語句影響的行數。
3.callproc(procname[, parameters])
執行存儲過程,procname 是存儲過程名,parameters 是爲存儲過程提供的參數。
4.fetchone()
從結果集中返回一條記錄的序列,如果沒有數據返回None 。
5.fetchmany([size=cursor.arraysize)
從結果集中返回小於或等於size 的記錄數序列,如果沒有數據返回空序列,size 默認情況下是整個遊標的行數。
6.fetchall()
從結果集中返回所有數據。


實列:

1. 創建數據庫:

import pymysql
#  連接數據庫
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='1234',
charset='utf8'
)
cursor = conn.cursor() #  拿到遊標
cursor.execute("create database if not exists mydatabase") #  創建數據庫
cursor.close() # 關閉遊標
conn.close() # 關閉連接

2. 創建數據庫表:

import pymysql
#  連接數據庫
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='1234',
db='mydatabase',
charset='utf8'
)
cursor = conn.cursor()  # 拿到遊標
cursor.execute('''create table if not exists student (
number varchar(20) primary key,
name varchar(50) not null,
sex varchar(2) check (sex in(‘M’,‘F’)),
math double(4,1),
english double(4,1),
computer double(4,1)
''')
cursor.close()
conn.close()

3. 插入數據:

import pymysql
# 1.  創建數據庫連接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='1234',
db='mydatabase'
charset='utf8'
)
try:
	# 2. 創建遊標對象
	with conn.cursor() as cursor: #with 代碼塊結束時就會關閉遊標對象。
		# 3. 執行sql 操作。插入多條語句
		sql = 'insert into student(number, name, sex, math, english, computer) values (%s, %s, %s, %s, %s, %s)'
		
		data = [
		('1501', ' 炎黃', 'M', 78.5, 70.0, 100.0),
		('1505', ' 呂萌萌', 'M', 100.0, 90.0, 95.0),
		('1509', ' 石耀舉', 'F', 60.5, 90.0, 70.0)
		]
		cursor.executemany(sql, data)
		
		# 3.  執行sql 操作 。插入 單條 數據
		data = ('1521', ' 王維', 'F', 68.4, 73.0, 55.0)
		cursor.execute(sql, data) #  參數放在列表中,或放在元組中
		# 4.  提交數據庫事務
		conn.commit()
	# with 代碼塊結束 5.  自動關閉遊標
except pymysql.DatabaseError:
	conn.rollback()  # 4.  回滾數據庫事務
finally:
	conn.close()# 6.  關閉數據庫連接

4. 刪除數據

import pymysql
# 1.  創建數據庫連接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='1234',
db='mydatabase'
charset='utf8'
)
try:
	# 2.  創建遊標對象
	with conn.cursor() as cursor:
		# 3.  執行sql 語句
		sql = 'delete from student where number=%s'
		cursor.execute(sql, '1502')
		cursor.executemany(sql, ('1505', '1507', '1514'))
		 # 4.  提交數據庫事務
		conn.commit()
		# with 代碼塊結束 5.  關閉遊標
except pymysql.DatabaseError:
	conn.rollback()# 4.  回滾數據庫事務
finally:
	conn.close()# 6.  關閉數據庫連接

5. 修改數據

import pymysql
# 1.  創建數據庫連接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='1234',
db='mydatabase'
charset='utf8'
)
try:
	#2.  創建遊標對象
	with conn.cursor() as cursor:
		# 3.  執行sql 語句
		sql = 'update student set name=%s where number > %s'
		cursor.execute(sql, (' 水份', '1510'))
		# 4.  提交數據庫事務
		conn.commit()
	# with 代碼塊結束 5.  關閉遊標
except pymysql.DatabaseError:
	# 4.  回滾數據庫事務
	conn.rollback()
finally:
	# 6.  關閉數據庫連接
	conn.close()

6. 查找數據

import pymysql
# 1.  創建數據庫連接
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='1234',
db='mydatabase'
charset='utf8'
)
try:
# 2. 創建遊標對象
with conn.cursor() as cursor:
	# 3. 執行sql 操作
	sql = 'select * from student'
	cursor.execute(sql)
	
	# 4. 提取結果集
	# 提取所有數據,返回結果默認是元組形式,所以可以進行迭代處理
	result_list = cursor.fetchall()
	for row in result_list:
	print(row)
	print(' 共查詢到:', cursor.rowcount, ' 條數據。')
	
	# 4. 提取結果集。獲取第一行數據
	result1 = cursor.fetchone()
	print(result1)
	
	# 4. 提取結果集。獲取前n 行數據
	result2 = cursor.fetchmany(2)
	print(result2)
	# with 代碼塊結束 5.  關閉遊標
finally:
	# 6.  關閉數據庫連接
	conn.close()

7. 數據庫配置文件的使用

配置文件configparser.ini

[db]
host = 127.0.0.1
port = 3306
user = root
password = 1234
database = mydatabase
charset = utf8
import pymysql
import configparser
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')
host = config['db']['host']
port = config.getint('db', 'port')
user = config['db']['user']
password = config['db']['password']
database = config['db']['database']
charset = config['db']['charset']

# 1. 創建數據庫連接
conn = pymysql.connect(
host=host,
port=port,
user=user,
password=password,
database=database,
charset=charset
)

cursor 就是一個Cursor 對象,這個cursor 是一個實現了迭代器和生成器的對象,這個時候cursor 中還沒有數據,只有等到fetchone() 或fetchall() 的時候才返回一個元組tuple ,才支持len() 和index() 操作,這也是它是迭代器的原因 。但同時爲什麼說它是生成器呢?因爲cursor 只能用一次,即每用完一次之後記錄其位置,等到下次再取的時候是從遊標處再取而不是從頭再來,而且fetch 完所有的數據之後,這個cursor 將不再有使用價值了,即不再能fetch 到數據了。

8. 學生管理系統

import pymysql
import wx
import wx.grid


class MyData():
    def __init__(self):
        self.tableText=["number","name","sex","math","english","computer"]
        self.mydata=[]
        self.conn = pymysql.connect(
            host="127.0.0.1",
            port=3306,
            user="root",
            password="123456",
            database="student",
            charset="utf8"
        )

    def Conn(self):
        self.conn = pymysql.connect(
            host="127.0.0.1",
            port=3306,
            user="root",
            password="123456",
            database="student",
            charset="utf8"
        )

    def showData(self,number):
        self.Conn()
        try:
            with self.conn.cursor() as cursor:
                self.mydata=[]
                if number=="":
                    sqlstr = "select * from test1"
                    cursor.execute(sqlstr, ())
                else:
                    sqlstr = "select * from test1 where number=%s"
                    cursor.execute(sqlstr, (number))

                result_list=cursor.fetchall()
                for item in result_list:
                    print(item)
                    self.mydata.append(item)
        except pymysql.DatabaseError:
            self.conn.rollback()
        finally:
            self.conn.close()

    def insterData(self,data):
        self.Conn()
        try:
            with self.conn.cursor() as cursor:
                sqlstr = """
                    insert into test1 (number,name,sex,math,english,computer)
                     values(%s,%s,%s,%s,%s,%s)
                    """
                cursor.execute(sqlstr, data)
                self.conn.commit()
        except pymysql.DatabaseError:
            self.conn.rollback()
        finally:
            self.conn.close()

    def uptateData(self,data):
        self.Conn()
        try:
            with self.conn.cursor() as cursor:
                sqlstr = "update test1 set number=%s,name= %s ,sex=%s,math=%s,english=%s,computer=%s where number=%s"
                cursor.execute(sqlstr, data)
                self.conn.commit()
        except pymysql.DatabaseError:
            self.conn.rollback()
        finally:
            self.conn.close()

    def deleteData(self,number):
        self.Conn()
        try:
            with self.conn.cursor() as cursor:
                sqlstr = "delete from test1 where number=%s"
                print(number)
                cursor.execute(sqlstr, number)
                self.conn.commit()
        except pymysql.DatabaseError:
            self.conn.rollback()
        finally:
            self.conn.close()
    def colse(self):
        self.conn.close()


class MyGridTable(wx.grid.GridTableBase):
    def __init__(self,tableText,data):
        super().__init__()
        self.tableText=tableText
        self.data=data
        self.colLabels=tableText
    def GetNumberRows(self):
        return len(self.data)
    def GetNumberCols(self):
        return len(self.tableText)
    def GetValue(self, row, col):
        return self.data[row][col]
    def GetColLabelValue(self, col):
        return self.tableText[col]

class AddorChangeFrame(wx.Frame):
    def __init__(self,frame):
        if frame=="添加":
            super().__init__(parent=None,size=(300,350),title="添加")
        else:
            super().__init__(parent=None, size=(300, 350), title="修改")
        self.Center()

        panel=wx.Panel(self)
        number=wx.StaticText(parent=panel,id=-1,label="學號")
        self.numbertext=wx.TextCtrl(parent=panel,id=-1)
        box1=wx.BoxSizer()
        box1.Add(number)
        box1.Add(self.numbertext)

        name = wx.StaticText(parent=panel, id=-1, label="姓名")
        self.nametext = wx.TextCtrl(parent=panel, id=-1)
        box2 = wx.BoxSizer()
        box2.Add(name)
        box2.Add(self.nametext)

        sex = wx.StaticText(parent=panel, id=-1, label="性別")
        self.sextext = wx.TextCtrl(parent=panel, id=-1)
        box3 = wx.BoxSizer()
        box3.Add(sex)
        box3.Add(self.sextext)

        math = wx.StaticText(parent=panel, id=-1, label="數學")
        self.mathtext = wx.TextCtrl(parent=panel, id=-1)
        box4 = wx.BoxSizer()
        box4.Add(math)
        box4.Add(self.mathtext)

        english = wx.StaticText(parent=panel, id=-1, label="英語")
        self.englishtext = wx.TextCtrl(parent=panel, id=-1)
        box5 = wx.BoxSizer()
        box5.Add(english)
        box5.Add(self.englishtext)

        computer = wx.StaticText(parent=panel, id=-1, label="學號")
        self.computertext = wx.TextCtrl(parent=panel, id=-1)
        box6 = wx.BoxSizer()
        box6.Add(computer)
        box6.Add(self.computertext)

        if frame=="添加":
            button1 = wx.Button(parent=panel, id=2, label="添加")
        else:
            button1=wx.Button(parent=panel,id=3,label="修改")
        button2 = wx.Button(parent=panel, id=1, label="取消")
        self.Bind(wx.EVT_BUTTON, self.on_button, id=1, id2=3)
        box7=wx.BoxSizer()
        box7.Add(button1)
        box7.Add(button2)


        mainbox=wx.BoxSizer(wx.VERTICAL)
        mainbox.Add(box1,1,flag=wx.ALL,border=5)
        mainbox.Add(box2,1,flag=wx.ALL,border=5)
        mainbox.Add(box3,1,flag=wx.ALL,border=5)
        mainbox.Add(box4,1,flag=wx.ALL,border=5)
        mainbox.Add(box5,1,flag=wx.ALL,border=5)
        mainbox.Add(box6,1,flag=wx.ALL,border=5)
        mainbox.Add(box7, 1, flag=wx.ALL, border=5)

        panel.SetSizer(mainbox)

    def on_button(self, event):
        id = event.GetId()
        number=self.numbertext.GetValue()
        name = self.nametext.GetValue()
        sex = self.sextext.GetValue()
        math = self.mathtext.GetValue()
        english=self.englishtext.GetValue()
        computer = self.computertext.GetValue()

        data = MyData()
        # 取消
        if id == 1:
            self.Close()
        # 添加
        elif id==2:
            data.insterData((number, name, sex, math, english, computer))
            self.Close()
        # 修改
        else:
            data.uptateData((number, name, sex, math, english, computer,number))
            self.Close()


class myFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None,size=(700,400),title="學生信息管理系統")
        self.Center()

        panel=wx.Panel(self)

        box1=wx.BoxSizer(wx.HORIZONTAL)
        text1=wx.StaticText(parent=panel,id=-1,label="請輸入學號:")
        self.inputtext=wx.TextCtrl(parent=panel,id=-1)
        findbutton=wx.Button(parent=panel,id=1,label="查詢")
        deletebutton = wx.Button(parent=panel, id=4, label="刪除")
        self.Bind(wx.EVT_BUTTON,self.on_button,id=1,id2=4)
        b = wx.BoxSizer(wx.HORIZONTAL)
        b.Add(text1,1,flag=wx.LEFT|wx.TOP|wx.BOTTOM,border=15)
        b.Add(self.inputtext, 1,flag=wx.ALL,border=10)
        b.Add(findbutton, 1,flag=wx.ALL,border=10)
        b.Add(deletebutton, 1, flag=wx.ALL, border=10)
        box1.Add(b,1,flag=wx.LEFT|wx.RIGHT,border=70)

        self.grid = wx.grid.Grid(parent=panel,size=(580,255))
        rowsizeinfo=wx.grid.GridSizesInfo(40,[])
        self.grid.SetRowSizes(rowsizeinfo)
        data=MyData()
        data.showData("")
        table = MyGridTable(data.tableText,data.mydata)
        self.grid.SetTable(table, True)
        box2 = wx.BoxSizer()
        box2.Add(self.grid)

        addbutton = wx.Button(parent=panel, id=2, label="添加")
        updatebutton = wx.Button(parent=panel, id=3, label="修改")


        box3 = wx.BoxSizer()
        box3.Add(addbutton,1,flag=wx.EXPAND)
        box3.Add(updatebutton, 1, flag=wx.EXPAND)


        mainbox = wx.BoxSizer(wx.VERTICAL)
        mainbox.Add(box1,1,flag=wx.EXPAND)
        mainbox.Add(box2, 1,flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=50)
        mainbox.Add(box3, 1,flag=wx.EXPAND)
        panel.SetSizer(mainbox)

    def on_button(self, event):
        id = event.GetId()
        data = MyData()
        if id == 1:
            data.showData(self.inputtext.GetValue())
            print("查詢!!!")
        elif id==2:
            print("添加!!!")
            self.addFrame=AddorChangeFrame("添加")
            self.addFrame.Show()
        elif id == 3:
            self.addFrame = AddorChangeFrame("修改")
            self.addFrame.Show()
            print("修改!!")
        elif id == 4:
            data.deleteData(self.inputtext.GetValue())
            print("刪除!!!")

        if id !=1:# 顯示全部
            data.showData("")
        table = MyGridTable(data.tableText, data.mydata)
        self.grid.SetTable(table,True)


class myApp(wx.App):
    def OnInit(self):
        self.frame=myFrame()
        self.frame.Show()
        return True


if __name__=="__main__":
    app=myApp()
    app.MainLoop()

在這裏插入圖片描述
在這裏插入圖片描述


人生的光榮,不在於永不言敗,而在於能夠屢撲屢起 !

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章