MySQL—ORM框架,sqlalchemy模塊
阿新 • • 發佈:2018-10-20
alex href 條件 upd 初識 有道 pytho imp list
武老師博客:ORM框架介紹
import os #1.當一類函數公用同樣參數時候,可以轉變成類運行 - 分類 #2.面向對象: 數據和邏輯組合在一起了 #3. 一類事物共同用有的屬性和行為(方法) #因此 表其實可以寫成一個類 #雙下方法item 和 call 必須要背會: class Userinfo: def __init__(self,id,name): self.id = id self.name = name def show(self): print(‘in the show面向對象復習‘) def __call__(self, *args, **kwargs): print(‘你在調用call雙下方法哦‘) def __getitem__(self, item): return self.__dict__[item] def __setitem__(self,key,value): self.__dict__[key] = value def __delitem__(self, key): del self.__dict__[key] user1= Userinfo(1,‘gkx‘) #類似表第一行 user1() user1[‘age‘] = 22 print(user1.__dict__) print(user1[‘id‘]) # del user1[‘age‘] #調用 __delitem__ 方法 del user1.age #原生方法 print(user1.__dict__)
#ORM : object relational mapper #1.ORM框架: ORM-->關系對象映射 : SQLAlchemy:code first,默認沒有db first,想有,要裝第三方工具ORM框架初識#作用 #1.提供簡單的規則 #2.自動轉換成sql語句 #兩類 # DB first / code first 所有的ORM都是創建一個類,讓類去對應表 ‘‘‘ DB first: 幫你從db中把已創建好的表,連上db後,自動把表轉化為代碼中的一個個類 Code first: 先有類和db,然後在數據庫創建表 - DB first: 手動創建數據庫以及表 -> ORM框架 -> 自動生成類 - code first: 手動創建類、和數據庫 -> ORM框架 -> 以及表 SQLAlchemy ‘‘‘ #20181011 ORM框架 圖在有道詞典 #SQLAlchemy 不進行連接,要用pymysql等進行連接 ‘‘‘ SQLAlchemy是Python編程語言下的一款ORM框架,該框架建立在數據庫API之上,使用關系對象映射進行數據庫操作, 簡言之便是:將對象轉換成SQL,然後使用數據API執行SQL並獲取執行結果。 SQLAlchemy本身無法操作數據庫,其必須以來pymsql等第三方插件,Dialect用於和數據API進行交流,根據配置文件的不同調用不同的數據庫API,從而實現對數據庫的操作,如: MySQL-Python mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多詳見:http://docs.sqlalchemy.org/en/latest/dialects/index.html ‘‘‘
sqlalchemy是codefirst
DB first: 幫你從db中把已創建好的表,連上db後,自動把表轉化為代碼中的一個個類
Code first: 先有類和db,然後在數據庫創建表
- DB first: 手動創建數據庫以及表 -> ORM框架 -> 自動生成類
- code first: 手動創建類、和數據庫 -> ORM框架 -> 以及表 SQLAlchemy
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import sessionmaker, relationship from sqlalchemy import create_engine Base = declarative_base() class UserType(Base): __tablename__ = ‘usertype‘ id = Column(Integer,primary_key=True,autoincrement=True) title = Column(String(32),nullable=True,index=True) class Users(Base): __tablename__ = ‘users‘ id = Column(Integer,primary_key=True,autoincrement=True) name = Column(String(32),nullable=True,index=True) email = Column(String(16),unique=True) user_type_id = Column(Integer,ForeignKey("usertype.id")) # __table_args__ = ( # UniqueConstraint(‘id‘,‘name‘,name=‘uix_id_name‘), # Index(‘ix_n_ex‘,‘name‘,‘email‘) # ) def create_db(): engine = create_engine("mysql+pymysql://root:[email protected]:3306/ORMdb?charset=utf8", max_overflow=5) Base.metadata.create_all(engine) # Base.metadata.drop_all(engine) #刪除類對應的所有表 def drop_db(): engine = create_engine("mysql+pymysql://root:[email protected]:3306/ORMdb?charset=utf8", max_overflow=5) Base.metadata.drop_all(engine) #刪除類對應的所有表 engine = create_engine("mysql+pymysql://root:[email protected]:3306/ORMdb?charset=utf8", max_overflow=5) Session = sessionmaker(bind=engine) session = Session() #類似pymysql中conn和cursor的綜合 #****增加**************** # obj1 = UserType(title=‘普通用戶‘) # session.add(obj1) # objs = [ # UserType(title=‘白銀用戶‘), # UserType(title=‘黃金用戶‘) # ] # session.add_all(objs) #****查詢**************** ‘‘‘ usertype_lst = session.query(UserType).all() print(session.query(UserType)) #----->> SELECT usertype.id AS usertype_id, usertype.title AS usertype_title FROM usertype print(usertype_lst) #一個列表,包含了usertype類中的每一個對象,而這每一個對象就對應usertype表的一行數據 for i in usertype_lst: print(i.id,i.title)#直接打印i會是一個對象的內存地址,應該這麽打印才有值 # ···usertype_lst = session.query(UserType.id).all() #如果query裏面不是一個類,而是一個屬性,那麽 usertype_lst是有值的,可以直接打印 ‘‘‘ # usertype_lst = session.query(UserType.id,UserType.title).filter(UserType.id > 2) #或者 UserType.id ==2 # for i in usertype_lst: # print(i.title) #****刪除**************** # session.query(UserType.id,UserType.title).filter(UserType.id > 2).delete() #****修改**************** # session.query(UserType.id,UserType.title).filter(UserType.id > 0).update({‘title‘:‘黑金‘}) # session.query(UserType.id,UserType.title).filter(UserType.id > 0).update({UserType.title:UserType.title + ‘x‘},synchronize_session=False) # session.query(UserType.id,UserType.title).filter(UserType.id > 0).update({‘title‘:UserType.title + 1},synchronize_session="evaluate") session.commit() session.close()用sqlalchemy創建類,及增刪該查
query: 類似select
filter:類似 where
【.】 : 類似sql裏的 空格 用來分割命令的
all : fetchone,fetchall,如果不加all,那麽打印ret就只是返回一句sql語句
#如果query裏是一個類,all的取值是一個個對象,如果query裏是一個 類.屬性 那麽ret可以直接打印出來
子查詢 select id,(select name from tb2 where id = xx) from tb2
#sqlalchemy 支持 分組,排序,連表,通配符,子查詢,limit,union,where
#如果語句很復雜,還支持 原生sql
#子查詢 select id,(select name from tb2 where id = xx) from tb2 #sqlalchemy 支持 分組,排序,連表,通配符,子查詢,limit,union,where #如果語句很復雜,還支持 原生sql from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import sessionmaker, relationship from sqlalchemy import create_engine Base = declarative_base() engine = create_engine("mysql+pymysql://root:[email protected]:3306/ORMdb?charset=utf8", max_overflow=5) Session = sessionmaker(bind=engine) session = Session() #類似pymysql中conn和cursor的綜合 ‘‘‘ # 條件 ret = session.query(Users).filter_by(name=‘alex‘).all() #filter_by內部調用的其實是filter,只是這裏用參數表示, filter Users.name=‘alex‘ 是表達式 ret = session.query(Users).filter(Users.id > 1, Users.name == ‘eric‘).all() #默認是and,除非聲明是or 見下方導入 or_ ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == ‘eric‘).all() ret = session.query(Users).filter(Users.id.in_([1,3,4])).all() # 人家in_就是規定要這麽寫啊 ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all() # ~ 表示非 not in ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name=‘eric‘))).all() from sqlalchemy import and_, or_ ret = session.query(Users).filter(and_(Users.id > 3, Users.name == ‘eric‘)).all() #因為默認是and,此處不聲明 and_也可以的 ret = session.query(Users).filter(or_(Users.id < 2, Users.name == ‘eric‘)).all() ret = session.query(Users).filter( or_( Users.id < 2, and_(Users.name == ‘eric‘, Users.id > 3), Users.extra != "" )).all() # 通配符 ret = session.query(Users).filter(Users.name.like(‘e%‘)).all() # 不要忘了通配符還有一個是 _ 表示一位 ret = session.query(Users).filter(~Users.name.like(‘e%‘)).all() # ~ 非的意思啦 # 限制 ret = session.query(Users)[1:2] # limit 1,2 # 排序 ret = session.query(Users).order_by(Users.name.desc()).all() ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all() # 分組 from sqlalchemy.sql import func #使用函數要導入函數模塊! ret = session.query(Users).group_by(Users.extra).all() ret = session.query( func.max(Users.id), func.sum(Users.id), func.min(Users.id)).group_by(Users.name).all() ret = session.query( func.max(Users.id), func.sum(Users.id), func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all() # 連表 ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all() # select * from Users,Favor where Users.id = Favor.nid #相當於inner join ret = session.query(Person).join(Favor).all() #如果兩個表有設置了foreign key ,那麽不用寫條件,自動關聯了 inner join ret = session.query(Person).join(Favor,isouter=True).all() #left join, right join呢? 表換一下位置就好了。。。 ret = session.query(Person).join(Favor, isouter=True).all() # 組合 q1 = session.query(Users.name).filter(Users.id > 2) q2 = session.query(Favor.caption).filter(Favor.nid < 2) ret = q1.union(q2).all() q1 = session.query(Users.name).filter(Users.id > 2) q2 = session.query(Favor.caption).filter(Favor.nid < 2) ret = q1.union_all(q2).all() ‘‘‘ #子查詢的正確寫法 : .subquery() .as_acalar() # 1. # select * from b where id in (select id from tb2) # 2 select * from (select * from tb) as B # q1 = session.query(UserType).filter(UserType.id > 0).subquery() # result = session.query(q1).all() # print(result) # 3 # select # id , # (select * from users where users.user_type_id=usertype.id) # from usertype; #第一次循環 拿到 id1 然後判斷id1與另一張表相等,拿到一個值 #第二次循環 拿到 id2 然後判斷id2與另一張表相等,拿到一個值... # session.query(UserType,session.query(Users).filter(Users.id == 1).subquery()) #錯誤寫法 # session.query(UserType,Users) #上面這麽寫,其實還是類似笛卡兒積,達不到子查詢的效果 # result = session.query(UserType.id,session.query(Users).as_scalar()) # print(result) # result = session.query(UserType.id,session.query(Users).filter(Users.user_type_id==UserType.id).as_scalar()) # print(result) session.commit() session.close()sqlalchemy—子查詢
通過設置relationship可以減少連表帶來的冗余代碼,只要通過 obj.relationship_name 就可以獲取表格整行數據
# 誰有foreign key relationship就寫在哪裏 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import sessionmaker, relationship from sqlalchemy import create_engine Base = declarative_base() engine = create_engine("mysql+pymysql://root:[email protected]:3306/ORMdb?charset=utf8", max_overflow=5) Session = sessionmaker(bind=engine) session = Session() #類似pymysql中conn和cursor的綜合 ‘‘‘ 獲取用戶信息以及與其關聯的用戶名稱: 用SQL的時候就是要先連表 ‘‘‘ # 問題1. 獲取用戶信息以及與其關聯的用戶類型名稱(FK,Relationship=>正向操作) # user_list = session.query(Users,UserType).join(UserType,isouter=True) # print(user_list) # for row in user_list: # print(row[0].id,row[0].name,row[0].email,row[0].user_type_id,row[1].title) # user_list = session.query(Users.name,UserType.title).join(UserType,isouter=True).all() # for row in user_list: # print(row[0],row[1],row.name,row.title) ‘‘‘誰有foreign key relationship就寫在哪裏 relationalship~~~~ class Users(Base): __tablename__ = ‘users‘ id = Column(Integer, primary_key=True, autoincrement=True) name = Column(VARCHAR(32), nullable=True, index=True) email = Column(VARCHAR(16), unique=True) user_type_id = Column(Integer,ForeignKey("usertype.id")) user_type = relationship("UserType",backref=‘xxoo‘) ***********創建關系! 這個backref是給usertype用的,即父表用的 然後就可以使用以下方法來獲取了,不用連表這麽麻煩了‘‘‘ # user_list = session.query(Users) # for row in user_list: # print(row.name,row.id,row.user_type.title) # 問題2. 獲取用戶類型 # type_list = session.query(UserType) 傳統方式 # for row in type_list: # print(row.id,row.title,session.query(Users).filter(Users.user_type_id == row.id).all()) # type_list = session.query(UserType) # for row in type_list: # print(row.id,row.title,row.xxoo) # 設置了backref後 # row.xxoo 就相當於 session.query(Users).filter(Users.user_type_id == row.id).all() """tb1 1 白金 2 黑金 obj.xx ==> [obj,obj...] #這叫做反向操作,設置了 backref=‘xx‘後 """ """tb2 1 方少偉 1 2 成套 1 3 小白 2 # 正向 ut = relationship(backref=‘xx‘) obj.ut ==> 相當於拿到 tb1 在id對應位置一整行數據 這叫做正向操作 """ session.commit() session.close()ORM: relationship
MySQL—ORM框架,sqlalchemy模塊