python資料庫操作mysql:pymysql、sqlalchemy常見用法詳解
本文例項講述了python資料庫操作mysql:pymysql、sqlalchemy常見用法。分享給大家供大家參考,具體如下:
相關內容:
- 使用pymysql直接操作mysql
- 建立表
- 查看錶
- 修改表
- 刪除表
- 插入資料
- 檢視資料
- 修改資料
- 刪除資料
- 使用sqlmary操作mysql
- 建立表
- 查看錶
- 修改表
- 刪除表
- 插入資料
- 檢視資料
- 修改資料
- 刪除資料
- 首發時間:2018-02-24 23:59
- 修改:
- 2018-06-15,發現自己關於pymysql寫了對於資料的操作示例,但沒有寫表結構的示例,於是新增上
直接操作mysql--pymysql:
直接操作mysql意思是利用python實現類似命令列模式下的mysql互動。
前提:
- 首先需要安裝python與mysql互動的庫【PyMySQL 是在 Python3 版本中用於連線 MySQL 伺服器的一個庫】:
- 安裝模組:pymysql:
pip3 install pymysql
或者在Pycharm中安裝
- 安裝模組:pymysql:
使用:
- 首先匯入模組:import pymysql
- 連線資料庫 :資料庫連線物件 = pymysql.connect("host="localhost",port=3306,user='root',passwd='123456',db='python_test') 【如果需要支援中文,則加上charset=”utf8”】
- 建立遊標【遊標用於執行sql語句和管理查詢到的結果】 :遊標物件 = 資料庫連線物件.cursor()
- 執行sql語句 :遊標物件.execute(SQL語句) ,返回值是受影響行數 【execute可以執行所有的sql語句,不論是表相關的,還是資料相關的。】
- 由於預設開始事務,如果涉及修改、插入,則需要提交:連線物件.commit() ;以及撤銷修改、插入的回滾:連線物件.rollback()
- executemany是同時執行多條sql語句【以多組引數的格式,executemany(self,query,args)】:
- 獲取結果:
-
獲取一條結果:data = 遊標物件.fetchone()
-
獲取全部結果:data=遊標物件.fetchall()
-
獲取指定數量結果:data=遊標物件.fetmany(x)
-
獲取結果後,就會將對應的結果刪掉,比如fetchone是獲取一條,那麼這一條就會從原來的結果中刪除
-
遊標物件.rowcount()可以獲得執行sql語句後受影響的行數
-
- 關閉遊標: 遊標物件.close()
- 關閉資料庫連線:資料庫連線物件.close()
示例:
1.建立連線:
import pymysql #建立連線 conn=pymysql.connect(host="localhost",user="root",passwd="123456",db="python_test") #建立遊標 cursor=conn.cursor() #..............操作過程 #關閉遊標 cursor.close() #關閉連線 conn.close()
2.執行建立表:
import pymysql conn=pymysql.connect(host="localhost",password="123456",db="it",charset="utf8") cursor=conn.cursor() sql=""" create table user( id int PRIMARY KEY auto_increment,username VARCHAR(20),password VARCHAR(20),address VARCHAR(35) ) """ cursor.execute(sql) conn.commit() cursor.close() conn.close()
3.執行查詢:
import pymysql #建立連線 conn=pymysql.connect(host="localhost",db="python_test",charset="utf8") #建立遊標 cursor=conn.cursor() cursor.execute("select * from student;") print(cursor.fetchone())#獲取一條 print(cursor.fetchmany(2))#獲取兩條 print(cursor.fetchall())#獲取結果集合中的全部 #關閉遊標 cursor.close() #關閉連線 conn.close()
4.執行插入、修改、刪除:
import pymysql #建立連線 conn=pymysql.connect(host="localhost",charset="utf8") #建立遊標 cursor=conn.cursor() print("-----------插入----------------") cursor.execute("insert into student values ('nazha',2000,'男');") cursor.execute("select * from student;") print(cursor.fetchall()) print("-----------插入----------------") #cursor.executemany(self,args) cursor.executemany("insert into student value(%s,%s,%s);",[('zhangsan',18,'男'),('lisi','男')]) cursor.execute("select * from student;") print(cursor.fetchall()) print("-----------修改----------------") cursor.execute("update student set name = 'zhangsan1' where name = 'zhangsan';") cursor.execute("select * from student;") print(cursor.fetchall()) print("----------刪除-----------------") cursor.execute("delete from student where name = 'lisi';") cursor.execute("select * from student;") print(cursor.fetchall()) print("---------------------------") #需要提交才能插入、成功修改、刪除 conn.commit() #關閉遊標 cursor.close() #關閉連線 conn.close()
結果:
(('lilei',('hanmeimei','女'),('huluwa',('sunwukong',('baigujing',3000,('nazha','男')) --------------------------- (('lilei',('zhangsan',('zhangsan1','男')) ---------------------------
5.設定支援中文【建立連線時新增charset=”utf8”】:
import pymysql #建立連線 # conn=pymysql.connect(host="localhost",db='python_test') conn=pymysql.connect(host="localhost",db='python_test',charset="utf8") #建立遊標 cursor = conn.cursor() effect_row= cursor.execute("select * from student;") print("執行成功,受影響行數:",effect_row) print(cursor.fetchall()) conn.commit() cursor.close() conn.close()
新增前:
新增後:
使用sqlalchemy操作mysql:
介紹:
- ORM 將資料庫中的表與面嚮物件語言中的類建立了一種對應關係,【ORM可以說是參照對映來處理資料的模型,比如說:需要建立一個表,可以定義一個類,而這個類存在與表相對映的屬性,那麼可以通過操作這個類來建立一個表】
- sqlmary是一個mysql的ORM
前提:
- 安裝模組:pip3 install sqlalchemy
使用:
- 匯入模組:
- 匯入連線資料庫模組:from sqlalchemy import create_engine
- 如果需要建立新表,則需要匯入表結構定義模組:from sqlalchemy.ext.declarative import declarative_base
- 匯入其他相關模組,主要是對映的類,如欄位對映為Column,如資料型別int對映為Integer,如索引對映為Index,需要什麼匯入什麼:from sqlalchemy import Column,Integer,String
- 對映關係:
資料庫中 對映 模組【如果可以從多個模組處匯入,用 | 分隔】【方式太多,可能有漏,但不影響匯入】 表 Table from sqlalchemy import Table int Integer from sqlalchemy.types import Integer 索引 Index from sqlalchemy import Index 欄位、列 Column from sqlalchemy import Column varchar VARCHAR、String from sqlalchemy.types import String | from sqlalchemy import String 外來鍵 ForeignKey from sqlalchemy import ForeignKey
- 連線資料庫:連線物件=create_engine('資料庫型別+資料庫驅動名稱://使用者名稱:口令@機器地址:埠號/資料庫名',編碼格式,echo)
- sqlalchemy支援多種API操作模式,可以使用不同的模式來連線操作資料庫:'資料庫型別+資料庫驅動名稱://使用者名稱:口令@機器地址:埠號/資料庫名'
- 比如pymsql【py3常用】:
mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>
- 比如pymsql【py3常用】:
- 其他引數:
- echo是否顯示ORM轉成實際sql語句的過程,echo=True為顯
encoding為連線時使用的字符集
- sqlalchemy支援多種API操作模式,可以使用不同的模式來連線操作資料庫:'資料庫型別+資料庫驅動名稱://使用者名稱:口令@機器地址:埠號/資料庫名'
操作:
基本操作:
- 建立新表
- 方法一: 使用declarative
- 1.匯入模組
from sqlalchemy.ext.declarative import declarative_base
- 2.根據需要的元素來匯入模組
from sqlalchemy import Column
- 匯入需要的資料型別【注:資料型別在sqlalchemy中也有指向,所以也可以
from sqlalchemy import String,Char
】:from sqlalchemy.types import *
- 匯入需要的資料型別【注:資料型別在sqlalchemy中也有指向,所以也可以
- 3.建立連線,
- 3.使用declarative_base來獲得一個類物件,此處我定義該物件為Base
- 定義一個類,繼承declarative_base生成的類物件Base
- 使用__tablename__來定義表名
- 使用 列名 = Column(資料型別,其他列屬性…)等類似格式來定義欄位
nullable=False
代表這一列不可以為空,index=True
表示在該列建立索
- 建立表:Base.metadata.create_all(engine)
from sqlalchemy import create_engine#負責匯入連線資料庫的物件 from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column #負責匯入列 from sqlalchemy.types import *#負責匯入列型別 #資料庫連線 engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8',echo=True) #方式一: Base = declarative_base() class User(Base): __tablename__ = 'user'#表名 id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) Base.metadata.create_all(engine)
- 1.匯入模組
- 方法二:使用Table
- 1.匯入模組:
from sqlalchemy import Table
- 2.連線資料庫:
engine=create_engine(….)
- 3.獲取meta類,
metadata=MetaData(engine)
- 4.建立Table物件( 比如:
t=Table("group",metadata,Column("id",primary_key=True),Column("group_name",String(32)))
) - 5.建立表:metadata.create_all()
from sqlalchemy import create_engine from sqlalchemy import Table from sqlalchemy import MetaData from sqlalchemy import Column from sqlalchemy.types import * from sqlalchemy.ext.declarative import declarative_base ####下面的註釋部分可以與上面一句的未註釋的替換 engine=create_engine("mysql+pymysql://root:123456@localhost/python_test",echo=True) metadata=MetaData(engine) ### # Base=declarative_base() t=Table( "group",#表名 # "group",Base.metadata,String(32)) ) metadata.create_all() # Base.metadata.create_all(engine)
- 1.匯入模組:
- 方法一: 使用declarative
- 查看錶:
- db_table=Base.metadata.tables#僅有當次執行中繼承了Base而建立的新表
- db_tables=engine.table_names()#僅有表名
- 刪除表:
Base.metadata.drop_all(engine)
- 修改表:
- 直接修改表所對應的類結構是無法修改成功的,
- 如果需要修改在程式中自定義的表的結構,那麼需要手動修改,手動的方式有很多,比如直接engine.execute(sql語句)。。。。
- 插入 資料【這裡僅針對使用declarative_base建立的表,對於不是程式中才建立的,可以自己使用declarative_base建一個類來對映之前的表,只要對映一致,就能插入資料】
- 1.連線資料庫:engine=create_engine(….)
- 1.匯入模組:from sqlalchemy.orm import sessionmaker
- 2.獲取session_class類:Session_class=sessionmaker(bind=engine)
- 3.獲取session物件:s=Session_class()
- 4.使用s來新增:
- s.add()
- s.add_all()
- 5.提交資料: s.commit()
from sqlalchemy import create_engine#負責匯入連線資料庫的物件 from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column #負責匯入列 from sqlalchemy.types import *#負責匯入列型別 #資料庫連線 engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",echo=True) Base = declarative_base() class User(Base): __tablename__ = 'user'#表名 id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) group = Column(Integer) Base.metadata.create_all(engine) from sqlalchemy.orm import sessionmaker obj1=User(name='lisi',password='123456',group=1) Session=sessionmaker(bind=engine) s=Session() s.add(obj1)# users=[User(name='wangwu',group=1),User(name='zhaoliu',User(name='sunqi',group=1) ] s.add_all(users)# s.commit()
- 查詢 資料
- 同樣適用sessionmaker來查詢,與插入相同,需要建立session_class物件(我定義為s)
- 使用s來查詢:
- s.query(表對應類)是相當於select對應表,後面可以跟first()、all()等來獲取結果,也可以加filter、filter_by等來篩選結果
- 獲取全部 : s.query(表對應類).all() 【返回的是一個結果列表】
- 查詢指定: s.query(表對應類).filter(表對應類.xxx==xxxx)【filter獲取的是結果集,需要使用all(),first()等方法來獲取結果】
- 查詢指定: s.query(表對應類).filter_by(xxx=xxxx)
附:雖然返回值是一個結果集,但這個集合是一個類物件,如果想檢視內容,需要在表對應的類中增加__repr__方法。
多個篩選條件使用“,”隔開
常見可用篩選條件【User是一個表對應的類】:
使用filter,filter_by時: User.name=='lisi'
User.name.like(“lisi%”))
User.name != 'lisi'
User.name.any() or_(篩選條件) 【代表裡面的多個篩選條件以or組合,需要匯入:from sqlalchemy import or_】 and_(篩選條件) 【代表裡面的多個篩選條件以and組合,需要匯入:from sqlalchemy import and_】【預設是and】 in_([篩選條件]) 【使用比如User.name.in_(['xiaxia','lilei','lover'])】 使用all時,以下是放在query裡面的: User.name [這相當於不使用where的select name from 表] 連線查詢使用:s.query(表對應類).join(表對應類.xxx==xxxx)
還有group_by,order_by等用法這裡不做講解[什麼時候有空再補吧!]
from sqlalchemy import create_engine#負責匯入連線資料庫的物件 from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column #負責匯入列 from sqlalchemy.types import *#負責匯入列型別 #資料庫連線 engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8') Base = declarative_base() class User(Base): __tablename__ = 'user'#表名 id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) group = Column(Integer) def __repr__(self): return "<id:%s name:%s group:%s>"%(self.id,self.name,self.group) Base.metadata.create_all(engine) from sqlalchemy.orm import sessionmaker obj1=User(name='lisi',group=1) Session=sessionmaker(bind=engine) s=Session() a=s.query(User).all() a2=s.query(User).filter(User.name=='lisi').first() a3=s.query(User).filter_by(name='lisi').first() print(a) print(a2) print(a3)
- 修改 資料:
- 修改資料的基礎是先查詢到資料,查詢:row=s.query(X).filter(X.xxx=xxx).first()
- 使用賦值語句修改 :row.xxx=xxxx
from sqlalchemy import create_engine#負責匯入連線資料庫的物件 from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column #負責匯入列 from sqlalchemy.types import *#負責匯入列型別 #資料庫連線 engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",group=1) Session=sessionmaker(bind=engine) s=Session() row=s.query(User).filter(User.name=='lisi').first() row.name='lisi2' s.commit()
- 刪除 資料:
- 刪除資料的基礎是先查詢到資料,查詢:row=s.query(X).filter(X.xxx=xxx)
- 使用delete刪除:row.delete()
# coding: utf-8 from sqlalchemy import create_engine#負責匯入連線資料庫的物件 from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column #負責匯入列 from sqlalchemy.types import *#負責匯入列型別 #資料庫連線 engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",primary_key=True) name = Column(String(32)) password = Column(String(64)) group = Column(Integer) def __repr__(self): return "<id:%s name:%s group:%s>"%(self.id,self.group) Base.metadata.create_all(engine) from sqlalchemy.orm import sessionmaker obj1=User(name='lisi',group=1) Session=sessionmaker(bind=engine) s=Session() a3=s.query(User).filter_by(name='lisi1') a3.delete() s.commit()
- 外來鍵相關:
- 外來鍵使用foregin_key建立
- 類中的relationship的作用:幫助ORM獲知他們的外來鍵關係,以便ORM使用外來鍵獲取相關資料
- relationship中的backref的用途:relationship使得可以在一個表中定義的relationshop能被兩個表使用,另一個表使用backref來獲取相關資訊
- relationship中的foreign_keys的用途:當有多個relationship時,為了避免ORM混淆多個relationship,特別的標註哪個外來鍵是哪個relationship
- relationship中的secondary的用途:在多對多的關係中,填入的值是中間表,維持兩邊表關係。
- 一對一的外來鍵關係:
- 1.匯入模組:from sqlalchemy import Foreign_key
- 2.建立外來鍵(如:group = Column(Integer,ForeignKey("group.id")),建立關係(如:group_relation=relationship('Group',backref="g_users")
- 3.插入資料
- 4.查詢到一條資料:如row=s.query(User).filter(User.name=='lisi').first()
- 5.嘗試A表呼叫關係來獲取B(row.group_relation.group_name),B使用backref來獲取A的資料(row2.g_users)
- 下面的例項大概就是“一個開發人員對應一個開發組的關係”
#負責匯入連線資料庫的物件 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column,ForeignKey #負責匯入列 from sqlalchemy.types import *#負責匯入列型別 from sqlalchemy.orm import relationship #資料庫連線 engine = create_engine("mysql+pymysql://root:123456@localhost/python_test",encoding ='utf-8') Base = declarative_base() class Group(Base): __tablename__="group" id=Column(Integer,primary_key=True) group_name=Column(String(32),nullable=False) def __repr__(self): return "<id:%s group_name:%s>"%(self.id,self.group_name) class User(Base): __tablename__ = 'user'#表名 id = Column(Integer,primary_key=True) name = Column(String(32),nullable=False) password = Column(String(64),nullable=False) group = Column(Integer,ForeignKey("group.id"))#這裡建立外來鍵 group_relation=relationship('Group',backref="g_users")#為ORM指明關係,方便ORM處理,第一個是對應的類 def __repr__(self): return "<id:%s name:%s>"%(self.id,self.name) Base.metadata.create_all(engine) from sqlalchemy.orm import sessionmaker # group1=Group(group_name='python') # group2=Group(group_name='linux') # group3=Group(group_name='AI') # user1=User(name='lisi',group=1) # user2=User(name='zhangsan',group=2) # user3=User(name='wangwu',group=3) # user4=User(name='lilei',group=3) Session=sessionmaker(bind=engine) s=Session() # s.add_all([group1,group2,group3,user1,user2,user3,user4]) # s.commit() # row=s.query(User).filter(User.name=='lisi').first() row=s.query(User).first() print(row.group_relation.group_name)#這裡User通過關係來獲取Group的資料 row2=s.query(Group).first() print(row2) print(row2.g_users)#這裡Group通過relationship的backref來獲取User的資料
- 一對多關係,外來鍵關聯
- 以一個老師能做一個班的班主任此外還能做另一個班的副班主任為例【即一個老師能對應多個班級】
- 一對多關係的建立的核心是relationship中的foreign_keys
- 附:當你建表成功而插入資料失敗時,可以嘗試先刪除掉資料表,有時候因為外來鍵依賴會導致插入失敗
#負責匯入連線資料庫的物件 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column,encoding ='utf-8') Base = declarative_base() class Grade(Base): __tablename__="grade" id=Column(Integer,primary_key=True) grade_name=Column(String(32),self.grade_name) class Teacher(Base): __tablename__ = 'teacher'#表名 id = Column(Integer,nullable=False) primary_grade = Column(Integer,ForeignKey("grade.id")) second_grade = Column(Integer,ForeignKey("grade.id")) primary_grade_relation=relationship('Grade',backref="first_teacher",foreign_keys=[primary_grade]) second_grade_relation=relationship('Grade',backref="second_teacher",foreign_keys=[second_grade]) def __repr__(self): return "<id:%s name:%s>"%(self.id,self.name) Base.metadata.create_all(engine) from sqlalchemy.orm import sessionmaker # grade1=Grade(grade_name='python') # grade2=Grade(grade_name='linux') # grade3=Grade(grade_name='AI') # grade4=Grade(grade_name='Java') # t1=Teacher(name='lisi',primary_grade=1,second_grade=2) # t2=Teacher(name='zhangsan',primary_grade=2,second_grade=1) # t3=Teacher(name='wangwu',primary_grade=4,second_grade=3) # t4=Teacher(name='lilei',primary_grade_relation=grade3,second_grade=4) #這裡外來鍵相關的比如primary_grade=x可以使用primary_grade_relation=物件來代替, # 會根據物件來轉成對應id,不過問題是不知道grade3的準確id,因為可能建立順序不一致 Session=sessionmaker(bind=engine) s=Session() # s.add_all([grade1,grade2,grade3,grade4]) # s.add_all([t1,t2,t3,t4]) # s.commit() row=s.query(Teacher).filter(Teacher.name=='lisi').first() print(row.name,row.primary_grade_relation.grade_name)#這裡Teacher通過關係來獲取Grade的資料 print(row.name,row.second_grade_relation.grade_name) row2=s.query(Grade).first() print(row2.grade_name,row2.first_teacher)#這裡Grade通過relationship的backref來獲取Teacher的資料 print(row2.grade_name,row2.second_teacher)
- 多對多外來鍵關聯
- 以選課中一門課能有多名學生,一個學生可以選多門課為示例:
- 其中relationship中的secondary的值是中間表,負責維持中間表與另外兩表的關係,建立多對多的核心是secondary
#負責匯入連線資料庫的物件 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base#負責匯入建立表的api from sqlalchemy import Column,encoding ='utf-8') Base = declarative_base() class SelectInfo(Base): __tablename__="selectClassInfo" id=Column(Integer,primary_key=True) sid=Column(Integer,ForeignKey("student.id")) cid=Column(Integer,ForeignKey("course.id")) """使用declarative_base和Table 建立表時,secondary的填寫不一樣 selectInfo2=Table( 'selectClassInfo',Column('sid',ForeignKey('student.id')) Column('cid',ForeignKey('student.id')) ) """ class Student(Base): __tablename__="student" id=Column(Integer,primary_key=True) name=Column(String(32),nullable=False) def __repr__(self): return "<id:%s name:%s>"%(self.id,self.name) class Course(Base): __tablename__ = 'course' id = Column(Integer,nullable=False) student_relation=relationship('Student',secondary="selectClassInfo",backref="courses") # student_relation=relationship('Student',secondary=selectClassInfo2,backref="courses") # #如果使用Table來建立中間表,上面是這樣填的 def __repr__(self): return "<id:%s name:%s>"%(self.id,self.name) Base.metadata.create_all(engine) from sqlalchemy.orm import sessionmaker # # s1=Student(name='lisi') # s2=Student(name='zhangsan') # s3=Student(name='wangwu') # s4=Student(name='lilei') # c1=Course(name='python',student_relation=[s1,s2]) # c2=Course(name='linux',student_relation=[s3]) # c3=Course(name='AI',student_relation=[s3,s4]) # c4=Course(name='Java') # c4.student_relation=[s1,s2,s3,s4]##在一邊增加關係之後,在secondary中會加入兩邊的資料 # # # Session=sessionmaker(bind=engine) s=Session() # s.add_all([s1,s4,c1,c2,c3,c4]) # s.commit() row=s.query(Course).filter(Course.id=='4').first() print(row.name,row.student_relation)#這裡Course通過關係來獲取Student的資料 row2=s.query(Student).filter(Student.id=="3").first() print(row2.name,row2.courses)#這裡Student通過relationship的backref來獲取Course的資料
補充說明:
1.engine 可以直接執行sql語句,方式是engine.execute(),返回值是結果集,可以使用fetchall等方法來獲取結果
2.其實建立表還有很多方法,可以使用各種物件來建立【比如在上面Table方式中也可以使用t來create(engine)】,但建議使用方式一
3.同樣的,不單建立表有各種方法,查看錶,刪除表等也有多種操作方式,也是因為可以使用多種物件來操作
4.session也可以直接執行sql語句: session.execute()
附上sessionmake API官方文件:http://docs.sqlalchemy.org/en/latest/orm/session_api.html裡面詳盡而簡單的講解了用法
以及一個第三方輔助文件:https://www.pythonsheets.com/notes/python-sqlalchemy.html 裡面有不少關於sqlalchemy的用法例子
更多關於Python相關內容感興趣的讀者可檢視本站專題:《Python常見資料庫操作技巧彙總》、《Python數學運算技巧總結》、《Python資料結構與演算法教程》、《Python函式使用技巧總結》、《Python字串操作技巧彙總》、《Python入門與進階經典教程》及《Python檔案與目錄操作技巧彙總》
希望本文所述對大家Python程式設計有所幫助。