SqlAlchemy ORM


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數據庫常用命令

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM