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数据库常用命令

 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!