SQLAlchemy
SQLAlchemy是Python編程語言下的一款ORM框架,該框架建立在數據庫API之上,使用關系對象映射進行數據庫操作,簡言之便是:將對象轉換成SQL,然后使用數據API執行SQL並獲取執行結果
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
使用 Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 進行數據庫操作。Engine使用Schema Type創建一個特定的結構對象,之后通過SQL Expression Language將該對象轉換成SQL語句,然后通過 ConnectionPooling 連接數據庫,再然后通過 Dialect 執行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 engine = create_engine("mysql+pymysql://user02:user02@192.168.33.35:3306/aaa?charset=utf8", max_overflow=5) # mysql+pymysql:固定格式 # user02:user02:用戶名及密碼 # @192.168.33.35:3306/ # aaa:數據庫名字 # ?charset=utf8:支持utf8 Base = declarative_base() # 生成orm基類 # 創建單表 class User(Base): __tablename__ = 'users' # 表名 id = Column(Integer, primary_key=True, autoincrement=True) # 主鍵自增 name = Column(String(50), index=True, nullable=True) # 創建索引並不能為空 extra = Column(String(50)) __table_args__ = ( UniqueConstraint('id', 'name', name='uix_id_name'), # 聯合唯一索引 Index('ix_id_name', 'name', 'extra'), # 聯合索引 ) # 一對多 class Colour(Base): __tablename__ = 'colour' # 表名 cid = Column(Integer, primary_key=True, autoincrement=True) colour = Column(String(20), server_default='red', unique=True) class Dress(Base): __tablename__ = 'dress' # 表名 did = Column(Integer, primary_key=True) name = Column(String(32), index=True, nullable=True) colour_id = Column(Integer, ForeignKey(Colour.cid)) # 多對多 class Group(Base): __tablename__ = 'group' id = Column(Integer, primary_key=True) name = Column(String(64), unique=True, nullable=False) class Server(Base): __tablename__ = 'server' id = Column(Integer, primary_key=True, autoincrement=True) hostname = Column(String(64), unique=True, nullable=False) class ServerToGroup(Base): __tablename__ = 'servertogroup' nid = Column(Integer, primary_key=True, autoincrement=True) server_id = Column(Integer, ForeignKey('server.id')) group_id = Column(Integer, ForeignKey('group.id')) def init_db(): Base.metadata.create_all(engine) # 創建表結構 init_db()
Foreignkey的2種寫法的區別:
是用第一種寫法,必須要注意順序,如果是用第二種,就隨意了
user_type_id = Column(Integer, ForeignKey(UserType.user_type_id)) # 使用這個寫法,必須把UserType表放在前面 user_type_id = Column(Integer, ForeignKey('user_type.user_type_id'))
也可以在類下面加上這個方法:
目的是在我們查詢的時候,都顯示的是方法,如果把該方法加入到相關類下面,返回的就是數據了
def __repr__(self): tmp = '%s - %s - %s - %s' % (self.id, self.name, self.extra, self.num) return tmp
刪除表
def drop_db(): Base.metadata.drop_all(engine)
最基本的增刪改查
add
Session = sessionmaker(bind=engine) session = Session() # 增(單條) obj1 = User(name='test1', extra='test1') session.add(obj1) # 增加單條 session.commit() # ============================================ # 增(多條) session.add_all([ User(name='test3', extra='test3'), User(name='test4', extra='test4'), ]) session.commit()
delete
# 刪除 session.query(User).filter(User.id > 4, User.extra == 'd').delete() session.commit()
update
session.query(User).filter(User.id > 4).update({User.name: 'test10'}) session.query(User).filter(User.id > 4).update({User.extra: User.extra + "111"}, synchronize_session=False) # 字符串拼接 session.query(User).filter(User.id > 4).update({User.num: User.num + 1}, synchronize_session="evaluate") # 數字相加 session.commit()
select
ret = session.query(User).all() # 已對象形式返回所有數據 ret = session.query(User.name, User.id).all() ret = session.query(User).filter_by(name='a').all() ret = session.query(User).filter_by(name='a').first()
進階篇增刪改查
select
ret = session.query(User).filter(User.id > 2, User.name == 'c').all() ret = session.query(User).filter(User.id.between(1, 3), User.name == 'c').all() ret = session.query(User).filter(User.id.in_([1, 3, 4])).all() ret = session.query(User).filter(~User.id.in_([1, 3, 4])).all() ret = session.query(User).filter(User.id.in_(session.query(User.id).filter_by(name='c'))).all() # 嵌套查詢
and、or
需要先導入模塊
from sqlalchemy import and_,or_
ret = session.query(User).filter(and_(User.id > 2, User.name == 'c')).all() ret = session.query(User).filter(or_(User.id > 2, and_(User.name == 'c'), User.extra != '')).all()
通配符
ret = session.query(User).filter(User.name.like('e%')).all() # 查詢已e開始的name字段 ret = session.query(User).filter(~User.name.like('e%')).all()
限制
ret = session.query(User)[1:4] # 這個不需要all
排序
ret = session.query(User).order_by(User.name.desc()).all() # 從高到低 ret = session.query(User).order_by(User.name.desc(), User.id.asc()).all()
groupby
需要先導入一個模塊
from sqlalchemy.sql import func
連表操作
ret = session.query(Colour, Dress).filter(Colour.cid == Dress.colour_id).all() print(ret) for i in ret: print(i.name) ret = session.query(Dress).join(Colour).all() # 默認是inner join ret = session.query(Dress).join(Colour, isouter=True).all() # 默認是left join sql = session.query(Dress.name, Colour.colour).join(Colour) # 輸出sql語句 print(sql) a = session.query(Dress.name, Colour.colour).join(Colour).all() print(a)
組合
q1 = session.query(User.name).filter(User.id > 4) q2 = session.query(Colour.colour).filter(Colour.colour == 'red') ret = q1.union(q2).all() # 默認去重 q1 = session.query(User.name).filter(User.id > 4) q2 = session.query(Colour.colour).filter(Colour.colour == 'red') ret = q1.union_all(q2).all() # 不去重
relationship
這個功能只是優化在你寫代碼過程中,進一步優化
一般情況下,relationship跟外鍵在一起,當用顯示存在obj.col這個方式的時候,我們一般叫正向查找,當使用backref叫做反向查找
正向查找:
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 engine = create_engine("mysql+pymysql://user02:user02@192.168.33.35:3306/aaa?charset=utf8", max_overflow=5) Base = declarative_base() # 生成orm基類 # 一對多 class Colour(Base): __tablename__ = 'colour' # 表名 cid = Column(Integer, primary_key=True, autoincrement=True) colour = Column(String(20), default='red', unique=True) class Dress(Base): __tablename__ = 'dress' # 表名 did = Column(Integer, primary_key=True) name = Column(String(32), index=True, nullable=True) colour_id = Column(Integer, ForeignKey(Colour.cid)) # 與生成表結構無關,僅用於查詢方便 col = relationship("Colour", backref='uuu') Session = sessionmaker(bind=engine) session = Session() ret = session.query(Dress).all() for obj in ret: # obj代指Dress的每一行數據 # obj.col代指group對象,封裝了Group里面的所有數據 print(obj.did, obj.name, obj.col.colour, obj.col.cid)
反向查找:
Session = sessionmaker(bind=engine) session = Session() obj = session.query(Colour).filter(Colour.colour == 'red').first() print(obj.cid) print(obj.colour) print(obj.uuu)
MySql數據庫常用命令