python數(shù)據(jù)庫(kù)操作mysql:pymysql、sqlalchemy常見用法詳解
本文實(shí)例講述了python數(shù)據(jù)庫(kù)操作mysql:pymysql、sqlalchemy常見用法。分享給大家供大家參考,具體如下:
相關(guān)內(nèi)容: 使用pymysql直接操作mysql 創(chuàng)建表 查看表 修改表 刪除表 插入數(shù)據(jù) 查看數(shù)據(jù) 修改數(shù)據(jù) 刪除數(shù)據(jù) 使用sqlmary操作mysql 創(chuàng)建表 查看表 修改表 刪除表 插入數(shù)據(jù) 查看數(shù)據(jù) 修改數(shù)據(jù) 刪除數(shù)據(jù) 首發(fā)時(shí)間:2018-02-24 23:59 修改: 2018-06-15,發(fā)現(xiàn)自己關(guān)于pymysql寫了對(duì)于數(shù)據(jù)的操作示例,但沒有寫表結(jié)構(gòu)的示例,于是添加上 直接操作mysql--pymysql:直接操作mysql意思是利用python實(shí)現(xiàn)類似命令行模式下的mysql交互。
前提: 首先需要安裝python與mysql交互的庫(kù)【PyMySQL 是在 Python3 版本中用于連接 MySQL 服務(wù)器的一個(gè)庫(kù)】: 安裝模塊:pymysql:pip3 install pymysql或者在Pycharm中安裝 使用: 首先導(dǎo)入模塊:import pymysql 連接數(shù)據(jù)庫(kù) :數(shù)據(jù)庫(kù)連接對(duì)象 = pymysql.connect('host='localhost',port=3306,user=’root’,passwd=’123456’,db=’python_test’) 【如果需要支持中文,則加上charset=”utf8”】 創(chuàng)建游標(biāo)【游標(biāo)用于執(zhí)行sql語(yǔ)句和管理查詢到的結(jié)果】 :游標(biāo)對(duì)象 = 數(shù)據(jù)庫(kù)連接對(duì)象.cursor() 執(zhí)行sql語(yǔ)句 :游標(biāo)對(duì)象.execute(SQL語(yǔ)句) ,返回值是受影響行數(shù) 【execute可以執(zhí)行所有的sql語(yǔ)句,不論是表相關(guān)的,還是數(shù)據(jù)相關(guān)的。】 由于默認(rèn)開始事務(wù),如果涉及修改、插入,則需要提交:連接對(duì)象.commit() ;以及撤銷修改、插入的回滾:連接對(duì)象.rollback() executemany是同時(shí)執(zhí)行多條sql語(yǔ)句【以多組參數(shù)的格式,executemany(self,query,args)】:
獲取結(jié)果:
獲取一條結(jié)果:data = 游標(biāo)對(duì)象.fetchone()
獲取全部結(jié)果:data=游標(biāo)對(duì)象.fetchall()
獲取指定數(shù)量結(jié)果:data=游標(biāo)對(duì)象.fetmany(x)
獲取結(jié)果后,就會(huì)將對(duì)應(yīng)的結(jié)果刪掉,比如fetchone是獲取一條,那么這一條就會(huì)從原來(lái)的結(jié)果中刪除
游標(biāo)對(duì)象.rowcount()可以獲得執(zhí)行sql語(yǔ)句后受影響的行數(shù)

import pymysql#創(chuàng)建連接conn=pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='python_test')#創(chuàng)建游標(biāo)cursor=conn.cursor()#..............操作過程#關(guān)閉游標(biāo)cursor.close()#關(guān)閉連接conn.close()2.執(zhí)行創(chuàng)建表:
import pymysqlconn=pymysql.connect(host='localhost',port=3306,user='root',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.執(zhí)行查詢:
import pymysql#創(chuàng)建連接conn=pymysql.connect(host='localhost',port=3306,user='root',passwd='123456',db='python_test',charset='utf8')#創(chuàng)建游標(biāo)cursor=conn.cursor()cursor.execute('select * from student;')print(cursor.fetchone())#獲取一條print(cursor.fetchmany(2))#獲取兩條print(cursor.fetchall())#獲取結(jié)果集合中的全部#關(guān)閉游標(biāo)cursor.close()#關(guān)閉連接conn.close()4.執(zhí)行插入、修改、刪除:
import pymysql#創(chuàng)建連接conn=pymysql.connect(host='localhost',port=3306,user='root',password='123456',db='python_test',charset='utf8')#創(chuàng)建游標(biāo)cursor=conn.cursor()print('-----------插入----------------')cursor.execute('insert into student values (’nazha’,2000,’男’);')cursor.execute('select * from student;')print(cursor.fetchall())print('-----------插入----------------')#cursor.executemany(self,query,args)cursor.executemany('insert into student value(%s,%s,%s);',[(’zhangsan’,18,’男’),(’lisi’,18,’男’)])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()#關(guān)閉游標(biāo)cursor.close()#關(guān)閉連接conn.close()
結(jié)果:
((’lilei’, 18, ’男’), (’hanmeimei’, 18, ’女’), (’huluwa’, 18, ’男’), (’sunwukong’, 18, ’男’), (’baigujing’, 3000, ’女’), (’nazha’, 2000, ’男’))---------------------------((’lilei’, 18, ’男’), (’hanmeimei’, 18, ’女’), (’huluwa’, 18, ’男’), (’sunwukong’, 18, ’男’), (’baigujing’, 3000, ’女’), (’nazha’, 2000, ’男’), (’zhangsan’, 18, ’男’), (’lisi’, 18, ’男’))---------------------------((’lilei’, 18, ’男’), (’hanmeimei’, 18, ’女’), (’huluwa’, 18, ’男’), (’sunwukong’, 18, ’男’), (’baigujing’, 3000, ’女’), (’nazha’, 2000, ’男’), (’zhangsan1’, 18, ’男’), (’lisi’, 18, ’男’))---------------------------((’lilei’, 18, ’男’), (’hanmeimei’, 18, ’女’), (’huluwa’, 18, ’男’), (’sunwukong’, 18, ’男’), (’baigujing’, 3000, ’女’), (’nazha’, 2000, ’男’), (’zhangsan1’, 18, ’男’))---------------------------5.設(shè)置支持中文【創(chuàng)建連接時(shí)添加charset=”utf8”】:
import pymysql#創(chuàng)建連接# conn=pymysql.connect(host='localhost',port=3306,user=’root’,passwd=’123456’,db=’python_test’)conn=pymysql.connect(host='localhost',port=3306,user=’root’,passwd=’123456’,db=’python_test’,charset='utf8')#創(chuàng)建游標(biāo)cursor = conn.cursor()effect_row= cursor.execute('select * from student;')print('執(zhí)行成功,受影響行數(shù):',effect_row)print(cursor.fetchall())conn.commit()cursor.close()conn.close()
添加前:
添加后:
from sqlalchemy import ForeignKey 連接數(shù)據(jù)庫(kù):連接對(duì)象=create_engine(’數(shù)據(jù)庫(kù)類型+數(shù)據(jù)庫(kù)驅(qū)動(dòng)名稱://用戶名:口令@機(jī)器地址:端口號(hào)/數(shù)據(jù)庫(kù)名’,編碼格式,echo) sqlalchemy支持多種API操作模式,可以使用不同的模式來(lái)連接操作數(shù)據(jù)庫(kù):’數(shù)據(jù)庫(kù)類型+數(shù)據(jù)庫(kù)驅(qū)動(dòng)名稱://用戶名:口令@機(jī)器地址:端口號(hào)/數(shù)據(jù)庫(kù)名’ 比如pymsql【py3常用】:mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options> 其他參數(shù): echo是否顯示ORM轉(zhuǎn)成實(shí)際sql語(yǔ)句的過程,echo=True為顯 encoding為連接時(shí)使用的字符集 操作:
基本操作:
創(chuàng)建新表 方法一: 使用declarative 1.導(dǎo)入模塊from sqlalchemy.ext.declarative import declarative_base2.根據(jù)需要的元素來(lái)導(dǎo)入模塊from sqlalchemy import Column 導(dǎo)入需要的數(shù)據(jù)類型【注:數(shù)據(jù)類型在sqlalchemy中也有指向,所以也可以from sqlalchemy import String,Integer,Char】:from sqlalchemy.types import *3.創(chuàng)建連接,3.使用declarative_base來(lái)獲得一個(gè)類對(duì)象,此處我定義該對(duì)象為Base定義一個(gè)類,繼承declarative_base生成的類對(duì)象Base 使用__tablename__來(lái)定義表名 使用 列名 = Column(數(shù)據(jù)類型,其他列屬性…)等類似格式來(lái)定義字段 nullable=False 代表這一列不可以為空,index=True 表示在該列創(chuàng)建索 創(chuàng)建表:Base.metadata.create_all(engine)from sqlalchemy import create_engine#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型#數(shù)據(jù)庫(kù)連接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) 方法二:使用Table 1.導(dǎo)入模塊: from sqlalchemy import Table2.連接數(shù)據(jù)庫(kù):engine=create_engine(….)3.獲取meta類,metadata=MetaData(engine)4.創(chuàng)建Table對(duì)象( 比如:t=Table('group' ,metadata,Column('id',Integer,primary_key=True),Column('group_name',String(32))) )5.創(chuàng)建表:metadata.create_all()
from sqlalchemy import create_enginefrom sqlalchemy import Tablefrom sqlalchemy import MetaDatafrom sqlalchemy import Columnfrom sqlalchemy.types import *from sqlalchemy.ext.declarative import declarative_base####下面的注釋部分可以與上面一句的未注釋的替換engine=create_engine('mysql+pymysql://root:123456@localhost/python_test',encoding =’utf-8’,echo=True)metadata=MetaData(engine) ### # Base=declarative_base()t=Table('group' ,metadata,#表名# 'group',Base.metadata,Column('id',Integer,primary_key=True),Column('group_name',String(32)))metadata.create_all()# Base.metadata.create_all(engine) 查看表: db_table=Base.metadata.tables#僅有當(dāng)次運(yùn)行中繼承了Base而創(chuàng)建的新表 db_tables=engine.table_names()#僅有表名 刪除表:Base.metadata.drop_all(engine) 修改表: 直接修改表所對(duì)應(yīng)的類結(jié)構(gòu)是無(wú)法修改成功的, 如果需要修改在程序中自定義的表的結(jié)構(gòu),那么需要手動(dòng)修改,手動(dòng)的方式有很多,比如直接engine.execute(sql語(yǔ)句)。。。。插入 數(shù)據(jù)【這里僅針對(duì)使用declarative_base創(chuàng)建的表,對(duì)于不是程序中才創(chuàng)建的,可以自己使用declarative_base建一個(gè)類來(lái)映射之前的表,只要映射一致,就能插入數(shù)據(jù)】 1.連接數(shù)據(jù)庫(kù):engine=create_engine(….) 1.導(dǎo)入模塊:from sqlalchemy.orm import sessionmaker 2.獲取session_class類:Session_class=sessionmaker(bind=engine) 3.獲取session對(duì)象:s=Session_class() 4.使用s來(lái)添加: s.add()s.add_all() 5.提交數(shù)據(jù): s.commit()
from sqlalchemy import create_engine#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型#數(shù)據(jù)庫(kù)連接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)) group = Column(Integer)Base.metadata.create_all(engine)from sqlalchemy.orm import sessionmakerobj1=User(name=’lisi’,password=’123456’,group=1)Session=sessionmaker(bind=engine)s=Session()s.add(obj1)#users=[User(name=’wangwu’,password=’123456’,group=1), User(name=’zhaoliu’, password=’123456’, group=1), User(name=’sunqi’, password=’123456’, group=1) ]s.add_all(users)#s.commit() 查找 數(shù)據(jù) 同樣適用sessionmaker來(lái)查找,與插入相同,需要?jiǎng)?chuàng)建session_class對(duì)象(我定義為s) 使用s來(lái)查找: s.query(表對(duì)應(yīng)類)是相當(dāng)于select對(duì)應(yīng)表,后面可以跟first()、all()等來(lái)獲取結(jié)果,也可以加filter、filter_by等來(lái)篩選結(jié)果獲取全部 : s.query(表對(duì)應(yīng)類).all() 【返回的是一個(gè)結(jié)果列表】查找指定: s.query(表對(duì)應(yīng)類).filter(表對(duì)應(yīng)類.xxx==xxxx)【filter獲取的是結(jié)果集,需要使用all(),first()等方法來(lái)獲取結(jié)果】查找指定: s.query(表對(duì)應(yīng)類).filter_by(xxx=xxxx)附:雖然返回值是一個(gè)結(jié)果集,但這個(gè)集合是一個(gè)類對(duì)象,如果想查看內(nèi)容,需要在表對(duì)應(yīng)的類中增加__repr__方法。多個(gè)篩選條件使用“,”隔開常見可用篩選條件【User是一個(gè)表對(duì)應(yīng)的類】: 使用filter,filter_by時(shí):
User.name==’lisi’
User.name.like(“l(fā)isi%”))
User.name != ’lisi’ User.name.any() or_(篩選條件) 【代表里面的多個(gè)篩選條件以or組合,需要導(dǎo)入:from sqlalchemy import or_】 and_(篩選條件) 【代表里面的多個(gè)篩選條件以and組合,需要導(dǎo)入:from sqlalchemy import and_】【默認(rèn)是and】 in_([篩選條件]) 【使用比如User.name.in_([’xiaxia’, ’lilei’, ’lover’])】 使用all時(shí),以下是放在query里面的: User.name [這相當(dāng)于不使用where的select name from 表] 連接查詢使用:s.query(表對(duì)應(yīng)類).join(表對(duì)應(yīng)類.xxx==xxxx)還有g(shù)roup_by,order_by等用法這里不做講解[什么時(shí)候有空再補(bǔ)吧!]
from sqlalchemy import create_engine#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型#數(shù)據(jù)庫(kù)連接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 sessionmakerobj1=User(name=’lisi’,password=’123456’,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) 修改 數(shù)據(jù): 修改數(shù)據(jù)的基礎(chǔ)是先查找到數(shù)據(jù),查找:row=s.query(X).filter(X.xxx=xxx).first() 使用賦值語(yǔ)句修改 :row.xxx=xxxx
from sqlalchemy import create_engine#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型#數(shù)據(jù)庫(kù)連接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 sessionmakerobj1=User(name=’lisi’,password=’123456’,group=1)Session=sessionmaker(bind=engine)s=Session()row=s.query(User).filter(User.name==’lisi’).first()row.name=’lisi2’s.commit() 刪除 數(shù)據(jù): 刪除數(shù)據(jù)的基礎(chǔ)是先查找到數(shù)據(jù),查找:row=s.query(X).filter(X.xxx=xxx) 使用delete刪除:row.delete()
# coding: utf-8from sqlalchemy import create_engine#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型#數(shù)據(jù)庫(kù)連接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 sessionmakerobj1=User(name=’lisi’,password=’123456’,group=1)Session=sessionmaker(bind=engine)s=Session()a3=s.query(User).filter_by(name=’lisi1’)a3.delete()s.commit()外鍵相關(guān): 外鍵使用foregin_key創(chuàng)建 類中的relationship的作用:幫助ORM獲知他們的外鍵關(guān)系,以便ORM使用外鍵獲取相關(guān)數(shù)據(jù) relationship中的backref的用途:relationship使得可以在一個(gè)表中定義的relationshop能被兩個(gè)表使用,另一個(gè)表使用backref來(lái)獲取相關(guān)信息 relationship中的foreign_keys的用途:當(dāng)有多個(gè)relationship時(shí),為了避免ORM混淆多個(gè)relationship,特別的標(biāo)注哪個(gè)外鍵是哪個(gè)relationship relationship中的secondary的用途:在多對(duì)多的關(guān)系中,填入的值是中間表,維持兩邊表關(guān)系。 一對(duì)一的外鍵關(guān)系: 1.導(dǎo)入模塊:from sqlalchemy import Foreign_key 2.建立外鍵(如:group = Column(Integer,ForeignKey('group.id')),建立關(guān)系(如:group_relation=relationship(’Group’,backref='g_users') 3.插入數(shù)據(jù) 4.查詢到一條數(shù)據(jù):如row=s.query(User).filter(User.name==’lisi’).first() 5.嘗試A表調(diào)用關(guān)系來(lái)獲取B(row.group_relation.group_name),B使用backref來(lái)獲取A的數(shù)據(jù)(row2.g_users) 下面的實(shí)例大概就是“一個(gè)開發(fā)人員對(duì)應(yīng)一個(gè)開發(fā)組的關(guān)系”
#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column,ForeignKey #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型from sqlalchemy.orm import relationship#數(shù)據(jù)庫(kù)連接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'))#這里創(chuàng)建外鍵 group_relation=relationship(’Group’,backref='g_users')#為ORM指明關(guān)系,方便ORM處理,第一個(gè)是對(duì)應(yīng)的類 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’,password=’123456’,group=1)# user2=User(name=’zhangsan’,password=’123456’,group=2)# user3=User(name=’wangwu’,password=’123456’,group=3)# user4=User(name=’lilei’,password=’123456’,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通過關(guān)系來(lái)獲取Group的數(shù)據(jù)row2=s.query(Group).first()print(row2)print(row2.g_users)#這里Group通過relationship的backref來(lái)獲取User的數(shù)據(jù)一對(duì)多關(guān)系,外鍵關(guān)聯(lián) 以一個(gè)老師能做一個(gè)班的班主任此外還能做另一個(gè)班的副班主任為例【即一個(gè)老師能對(duì)應(yīng)多個(gè)班級(jí)】 一對(duì)多關(guān)系的創(chuàng)建的核心是relationship中的foreign_keys 附:當(dāng)你建表成功而插入數(shù)據(jù)失敗時(shí),可以嘗試先刪除掉數(shù)據(jù)表,有時(shí)候因?yàn)橥怄I依賴會(huì)導(dǎo)致插入失敗
#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column,ForeignKey #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型from sqlalchemy.orm import relationship#數(shù)據(jù)庫(kù)連接engine = create_engine('mysql+pymysql://root:123456@localhost/python_test',encoding =’utf-8’)Base = declarative_base()class Grade(Base): __tablename__='grade' id=Column(Integer,primary_key=True) grade_name=Column(String(32),nullable=False) def __repr__(self): return '<id:%s group_name:%s>'%(self.id,self.grade_name)class Teacher(Base): __tablename__ = ’teacher’#表名 id = Column(Integer,primary_key=True) name = Column(String(32),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)#這里外鍵相關(guān)的比如primary_grade=x可以使用primary_grade_relation=對(duì)象來(lái)代替,# 會(huì)根據(jù)對(duì)象來(lái)轉(zhuǎn)成對(duì)應(yīng)id,不過問題是不知道grade3的準(zhǔn)確id,因?yàn)榭赡軇?chuàng)建順序不一致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通過關(guān)系來(lái)獲取Grade的數(shù)據(jù)print(row.name,row.second_grade_relation.grade_name)row2=s.query(Grade).first()print(row2.grade_name,row2.first_teacher)#這里Grade通過relationship的backref來(lái)獲取Teacher的數(shù)據(jù)print(row2.grade_name,row2.second_teacher) 多對(duì)多外鍵關(guān)聯(lián) 以選課中一門課能有多名學(xué)生,一個(gè)學(xué)生可以選多門課為示例: 其中relationship中的secondary的值是中間表,負(fù)責(zé)維持中間表與另外兩表的關(guān)系,創(chuàng)建多對(duì)多的核心是secondary
#負(fù)責(zé)導(dǎo)入連接數(shù)據(jù)庫(kù)的對(duì)象from sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_base#負(fù)責(zé)導(dǎo)入創(chuàng)建表的apifrom sqlalchemy import Column,ForeignKey #負(fù)責(zé)導(dǎo)入列from sqlalchemy.types import *#負(fù)責(zé)導(dǎo)入列類型from sqlalchemy.orm import relationship#數(shù)據(jù)庫(kù)連接engine = create_engine('mysql+pymysql://root:123456@localhost/python_test',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 創(chuàng)建表時(shí),secondary的填寫不一樣selectInfo2=Table(’selectClassInfo’,Base.metadata,Column(’sid’,Integer,ForeignKey(’student.id’))Column(’cid’,Integer,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,primary_key=True) name = Column(String(32),nullable=False) student_relation=relationship(’Student’,secondary='selectClassInfo',backref='courses') # student_relation=relationship(’Student’,secondary=selectClassInfo2,backref='courses') # #如果使用Table來(lái)創(chuàng)建中間表,上面是這樣填的 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]##在一邊增加關(guān)系之后,在secondary中會(huì)加入兩邊的數(shù)據(jù)###Session=sessionmaker(bind=engine)s=Session()# s.add_all([s1,s2,s3,s4,c1,c2,c3,c4])# s.commit()row=s.query(Course).filter(Course.id==’4’).first()print(row.name,row.student_relation)#這里Course通過關(guān)系來(lái)獲取Student的數(shù)據(jù)row2=s.query(Student).filter(Student.id=='3').first()print(row2.name,row2.courses)#這里Student通過relationship的backref來(lái)獲取Course的數(shù)據(jù)補(bǔ)充說(shuō)明:
1.engine 可以直接運(yùn)行sql語(yǔ)句,方式是engine.execute(),返回值是結(jié)果集,可以使用fetchall等方法來(lái)獲取結(jié)果
2.其實(shí)創(chuàng)建表還有很多方法,可以使用各種對(duì)象來(lái)創(chuàng)建【比如在上面Table方式中也可以使用t來(lái)create(engine)】,但建議使用方式一
3.同樣的,不單創(chuàng)建表有各種方法,查看表,刪除表等也有多種操作方式,也是因?yàn)榭梢允褂枚喾N對(duì)象來(lái)操作
4.session也可以直接運(yùn)行sql語(yǔ)句: session.execute()
附上sessionmake API官方文檔:http://docs.sqlalchemy.org/en/latest/orm/session_api.html里面詳盡而簡(jiǎn)單的講解了用法
以及一個(gè)第三方輔助文檔:https://www.pythonsheets.com/notes/python-sqlalchemy.html 里面有不少關(guān)于sqlalchemy的用法例子
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python常見數(shù)據(jù)庫(kù)操作技巧匯總》、《Python數(shù)學(xué)運(yùn)算技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
相關(guān)文章:
1. html中的form不提交(排除)某些input 原創(chuàng)2. ASP常用日期格式化函數(shù) FormatDate()3. 開發(fā)效率翻倍的Web API使用技巧4. XMLHTTP資料5. CSS3實(shí)現(xiàn)動(dòng)態(tài)翻牌效果 仿百度貼吧3D翻牌一次動(dòng)畫特效6. asp.net core項(xiàng)目授權(quán)流程詳解7. vue使用moment如何將時(shí)間戳轉(zhuǎn)為標(biāo)準(zhǔn)日期時(shí)間格式8. CSS3中Transition屬性詳解以及示例分享9. jsp文件下載功能實(shí)現(xiàn)代碼10. ASP動(dòng)態(tài)網(wǎng)頁(yè)制作技術(shù)經(jīng)驗(yàn)分享
