sql decimal 转string_SQL基础丨SQLAlchemy

d311207105cca5501254029646bee079.png

ORM框架

052a227b3f099e196ee22a388d5ed262.png

ORM提供了一种持久化模式,可以高效地对数据库进行访问。ORM的英文是Object Relation Mapping,中文叫做对象关系映射。是RDBMS和业务实体对象之间的一个映射,把底层的RDBMS封装成业务实体对象,提供给业务逻辑层使用。

ORM可以兼容多种DBMS,但是会在性能上有一些损失,而且对于一些复杂的数据查询,直接编写SQL反而会更简单有效。

Python中的ORM框架有哪些

Python有三种主流的ORM框架:

- Django,它是Python的web应用开发框架。采用了MTV的框架模式。

一个Model映射到一个数据表

05d398f47cb87b8d7ee78dd6bfd30eea.png

- SQLAlchemy,他也是Python中常用的ORM框架之一。提供了SQL工具包以及ORM工具。

- peewee,轻量级的ORM框架,简单易用。采用了Model类、Field实例和Model实例来于数据库建立映射关系,从而完成面向对象的管理方式。

使用SQLAlchemy来操作MySQL

安装相应的工具包

pip install sqlalchemy初始化数据库连接from sqlalchemy import create_engine# 初始化数据库连接,修改为你的数据库用户名和密码engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/wucai')

创建模型

# 定义Player对象:class Player(Base):    # 表的名字:    __tablename__ = 'player'    # 表的结构:    player_id = Column(Integer, primary_key=True, autoincrement=True)    team_id = Column(Integer)    player_name = Column(String(255))    height = Column(Float(3,2))

__tablename__指明了模型对应的数据表名称,即player数据表。同时在player模型中对采用的变量名进行定义,变量名需要和数据表中的字段名称保持一致,否则找不到数据表中的字段。

在SQLAlchemy中,采用Column对字段进行定义

b8878fa1dd48ef7f2fc43e78f7919d89.png

Column的参数,可以对对象创建列约束

36e572a57771a81f813f57c5ad8ec615.png

对数据表进行增删改查

示例

- 给player表增加一个新球员,姓名为“约翰科林斯”,球队ID未1003,身高为2.08

# 创建DBSession类型:DBSession = sessionmaker(bind=engine)# 创建session对象:session = DBSession()# 创建Player对象:new_player = Player(team_id = 1003, player_name = "约翰-科林斯", height = 2.08)# 添加到session:session.add(new_player)# 提交即保存到数据库:session.commit()# 关闭session:session.close()

首先初始化DBSession,相当于创建一个数据库的会话示例session。通过session来完成新球员的添加。

然后把创建好的对象new_player添加到session中,提交到数据库即可完成添加数据的操作。

查询数据

示例

- 查询身高>=2.08m的球员

#增加to_dict()方法到Base类中def to_dict(self):    return {c.name: getattr(self, c.name, None)            for c in self.__table__.columns}#将对象可以转化为dict类型Base.to_dict = to_dict# 查询身高>=2.08的球员有哪些rows = session.query(Player).filter(Player.height >= 2.08).all()print([row.to_dict() for row in rows])

运行结果

[{'player_id': 10003, 'team_id': 1001, 'player_name': '安德烈-德拉蒙德', 'height': Decimal('2.1100000000')}, {'player_id': 10004, 'team_id': 1001, 'player_name': '索恩-马克', 'height': Decimal('2.1600000000')}, {'player_id': 10009, 'team_id': 1001, 'player_name': '扎扎-帕楚里亚', 'height': Decimal('2.1100000000')}, {'player_id': 10010, 'team_id': 1001, 'player_name': '乔恩-洛伊尔', 'height': Decimal('2.0800000000')}, {'player_id': 10011, 'team_id': 1001, 'player_name': '布雷克-格里芬', 'height': Decimal('2.0800000000')}, {'player_id': 10015, 'team_id': 1001, 'player_name': '亨利-埃伦森', 'height': Decimal('2.1100000000')}, {'player_id': 10023, 'team_id': 1002, 'player_name': '多曼塔斯-萨博尼斯', 'height': Decimal('2.1100000000')}, {'player_id': 10024, 'team_id': 1002, 'player_name': '迈尔斯-特纳', 'height': Decimal('2.1100000000')}, {'player_id': 10032, 'team_id': 1002, 'player_name': 'TJ-利夫', 'height': Decimal('2.0800000000')}, {'player_id': 10033, 'team_id': 1002, 'player_name': '凯尔-奥奎因', 'height': Decimal('2.0800000000')}, {'player_id': 10037, 'team_id': 1002, 'player_name': '伊凯·阿尼博古', 'height': Decimal('2.0800000000')}, {'player_id': 10038, 'team_id': 1003, 'player_name': '约翰-科林斯', 'height': Decimal('2.0800000000')}]

如果对整个数据行进行查询,采用的是session.query(Player),相当于使用的是SELECT *。

在进行查询的时候,使用的是filter方法,对应的是SQL中的WHERE条件查询。

如果是AND的关系,如查询身高>=2.08,同时身高<=2.10的球员

rows = session.query(Player).filter(Player.height >=2.08, Player.height <=2.10).all()

使用了SQLAlchemy的or_操作符,使用之前要引入,即from sqlalchemy import or_

除了多条件查询,SQLAlchemy也支持分组查询、排序和返回指定数量的结果

示例

- 按照team_id进行分组,同时筛选分组后数据行数大于5的分组,并且按照分组后数据行数递增的顺序进行排序,显示team_id字段,以及每个分组的数据行数。

from sqlalchemy import funcrows = session.query(Player.team_id, func.count(Player.player_id)).group_by(Player.team_id).having(func.count(Player.player_id)>5).order_by(func.count(Player.player_id).asc()).all()print(rows)

运行结果

[(1001, 20), (1002, 17)]

注意事项:

- 把需要显示的字段Player.team_id,func.count(Player.player_id)作为query的参数,要用到sqlalchemy的func类,它提供了各种聚集函数。

- 在query()后面使用了group_by()进行分组,参数设置为Player.team_id字段,再使用having对分组条件进行筛选,参数func.count(Player.player_id)>5

- 使用order_by进行排序,参数为func.count(Player.player_id).asc(),也就是按照分组后的数据行数递增的顺序进行排序,最后使用.all()方法需要返回全部的数据。

删除数据

示例

- 删除姓名为约翰科林斯的球员

row = session.query(Player).filter(Player.player_name=='约翰-科林斯').first()session.delete(row)session.commit()session.close()

注:判断球员是否为约翰科林斯,需要使用(==)

修改数据

示例

- 修改球员索恩马克的身高改成2.17

row = session.query(Player).filter(Player.player_name=='索恩-马克').first()row.height = 2.17session.commit()session.close()

总结

f831b694d66d309805d590c168252bcb.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值