要使用SQLAlchemy进行数据处理必须要先构建session对象,所有和数据库的ORM操作都必须通过一个叫做session的会话对象来实现,通过以下代码来获取会话对象:
from sqlalchemy.orm import sessionmaker
engine = create_engine(DB_URL)
session = sessionmaker(engine)()
下面示例代码中的insert_data()可以为数据库添加数据,
from sqlalchemy import create_engine
from sqlalchemy import Column, String, Integer, Enum, DateTime
from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.ext.declarative import declarative_base
import enum
from datetime import datetime
from sqlalchemy.orm import sessionmaker
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'test'
USERNAME = 'root'
PASSWORD = '******'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
engine = create_engine(DB_URI)
Base = declarative_base(engine)
class Hobby(enum.Enum):
h1 = "抽烟"
h2 = "喝酒"
h3 = "烫头"
class Student(Base):
__tablename__ = "student"
name = Column(String(10), primary_key=True, nullable=False)
sid = Column(Integer)
age = Column(Integer)
hobby = Column(Enum(Hobby))
native_language = Column(Enum("中文", "英文"))
score = Column(Integer)
create_time = Column(DateTime, onupdate=datetime.now, default=datetime.now)
introduce = Column(LONGTEXT)
session = sessionmaker(engine)() # 构建session对象
def insert_data():
p1 = Student(name="张三", sid=1, age=20) # 添加数据内容
session.add(p1) # 通过session对象,将数据送往数据库
session.commit() # 提交
if __name__ == '__main__':
insert_data()
若要添加多条数据,只需将inset_data()方法改写,
def insert_data():
p1 = Student(name="李四", sid=2, age=20)
p2 = Student(name="王五", sid=3, age=20)
session.add_all([p1, p2]) # 使用add_all()方法
session.commit()
通过session.query(ORM模型名).filter_by(条件).all()可以查询到相应的所有数据,例如,
def search_data():
students = session.query(Student).filter_by(age=20).all()
for student in students:
print(student)
为了直观的看到数据,需要对ORM模型的__str__()魔术方法进行改写。
下面是查询数据相关的方法,
# 查找某个模型对应的那个表中所有的数据:
students = session.query(Student).all()
# 使用filter_by来做条件查询
students = session.query(Student).filter_by(age=20).all()
# 使用filter来做条件查询
students = session.query(Student).filter(Student.age=20).all()
# 使用get方法查找数据,get方法是根据id来查找的,只会返回一条数据或者None
student = session.query(Student).get(primary_key)
# 使用first方法获取结果集中的第一条数据
student = session.query(Student).first()
删除数据只将需要删除的数据从数据库中查找出来,然后使用session.delete()方法将这条数据从数据库中删除,最后做commit()操作就可以了。例如,
def delete_data():
student = session.query(Student).filter(Student.name=="李四").first() # 查找数据
session.delete(student)
session.commit()
该方法为删除一条数据,如果有多条数据需要循环删除,例如,
def delete_data():
students = session.query(Student).filter_by(sid=2).all() # 查找数据
for student in students: # 循环删除数据
session.delete(student)
session.commit()
更新数据只将需要更新的数据从数据库中查找出来,然后直接修改对应的属性值(字段值),最后做commit()操作就可以了。例如,
def update_data():
student = session.query(Student).filter(Student.sid==2).first() # 查找数据
student.sid = 3 # 修改sid值
session.commit()
同样,若要批量更新数据,需要进行循环更新,例如,
def update_data():
students = session.query(Student).filter_by(sid=1).all() # 查找数据
for student in students: # 循环更新数据
student.age = 30
session.commit()
query参数 | 功能 |
---|---|
模型对象名称 | 指定查找这个模型中所有的对象 |
模型对象名称.属性 | 可以指定只查找某个模型的其中几个属性(字段) |
func.count | 统计行的数量 |
func.avg | 求平均值 |
func.max | 求最大值 |
func.min | 求最小值 |
func.sum | 求和 |
注意,需要提前导入func模块才能使用相关聚合函数,
from sqlalchemy import func
func上,其实没有任何聚合函数。但是因为他底层做了一些魔术,只要mysql中有的聚合函数,都可以通过func调用。
过滤是数据提取的一个很重要的功能,以下对一些常用的过滤条件进行解释,并且这些过滤条件都是只能通过filter方法实现的:
过滤条件 | 示例 |
---|---|
equals | filter(Article.title == “title0”) |
not equals | filter(User.name != ‘ed’) |
like | filter(User.name.like(’%ed%’)) |
in | filter(User.name.in_([‘ed’,‘wendy’,‘jack’])) filter(User.name.in_(session.query(User.name).filter(User.name.like(’%ed%’)))) |
not in | filter(User.name.in_([‘ed’,‘wendy’,‘jack’])) |
is null | filter(User.name==None)或者filter(User.name.is_(None)) |
is not null | filter(User.name != None)或者filter(User.name.isnot(None)) |
and | filter(and_(User.name==‘ed’,User.fullname==‘Ed Jones’)) filter(User.name==‘ed’,User.fullname==‘Ed Jones’) filter(User.name==‘ed’).filter(User.fullname==‘Ed Jones’) |
or | filter(or_(User.name==‘ed’,User.name==‘wendy’)) |
注意,and和or都需要提前导入,
from sqlalchemy import and_, or_
如果想要查看orm底层转换的sql语句,可以在filter方法后面不要再执行任何方法直接打印就可以看到了,例如,
articles=session.query(Article).filter(or_(Article.title=='abc',Article.content=='abc'))
print(articles)