SqlAlchemy ORM
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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:[email protected]: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:[email protected]: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数据库常用命令
以上是关于SqlAlchemy ORM的主要内容,如果未能解决你的问题,请参考以下文章