Python3-ORM-Sqlalchemy
时间:2022-03-15 12:04
目录:
- ORM介绍
- sqlalchemy安装
- sqlalchemy基本使用
- 多外键关联
- 多对多关系
- 表结构设计作业
1. ORM介绍
orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,
为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,
而不用直接使用sql语言。
orm的优点:
- 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
- ORM使我们构造固化数据结构变得简单易行。
缺点:
- 无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。
- 现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的。
2. sqlalchemy安装
在Python中,最有名的ORM框架是SQLAlchemy。用户包括openstack\Dropbox等知名公司或应用,主要用户列表http://www.sqlalchemy.org/organizations.html#openstack
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
安装sqlalchemy
pip install SQLAlchemy<br><br>pip install pymysql #由于mysqldb依然不支持py3,所以这里我们用pymysql与sqlalchemy交互
3.sqlalchemy基本使用
sql原生语句创建表:
CREATE TABLE user ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(32), password VARCHAR(64), PRIMARY KEY (id) )
orm,实现上面同样的功能,代码如下:
第1种创建表结构的方法:
table_structure.py
#Author:Yun import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String engine = create_engine("mysql+pymysql://root:yun258762@localhost/test_db", encoding=‘utf-8‘, echo=True) Base = declarative_base() # 生成orm基类 class User(Base): __tablename__ = ‘user‘ # 表名 id = Column(Integer, primary_key=True) name = Column(String(32)) password = Column(String(64)) Base.metadata.create_all(engine) # 创建表结构
懒惰连接
当create_engine()第一次返回时,引擎实际上还没有尝试连接到数据库; 只有在第一次要求它对数据库执行任务时才会发生这种情况。
第2种创建表结构的方法:
#Author:Yun from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey from sqlalchemy.orm import mapper from sqlalchemy import create_engine metadata = MetaData()#生成metadata类 #创建user表,继承metadata类
#Engine使用Schama Type创建一个特定的结构对象 user = Table(‘new_user‘, metadata, Column(‘id‘, Integer, primary_key=True), Column(‘name‘, String(50)), Column(‘fullname‘, String(50)), Column(‘password‘, String(12)) ) class User(object): def __init__(self, name, fullname, password): self.name = name self.fullname = fullname self.password = password #表元数据是使用Table构造单独创建的,然后通过mapper()函数与User类相关联 mapper(User, user) # 通过ConnectionPooling 连接数据库 engine = create_engine("mysql+pymysql://root:yun258762@192.168.176.139/test_db?charset=utf8", max_overflow=5, echo=True) # 通过Dialect执行SQL metadata.create_all(engine) #创建表结构
事实上,我们用第1种方式创建的表就是基于第2种方式的再封装。
表已经创建好了开始数据操作:
增加数据:
#Author:Yun import table_structure#导入表结构模块 from sqlalchemy.orm import sessionmaker Session_class = sessionmaker(bind=table_structure.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 Session = Session_class() # 生成session实例#cursor user_obj = table_structure.User(name="王昭君", password="123456") # 生成你要创建的数据对象 user_obj2 = table_structure.User(name="韩信", password="123456") # 生成你要创建的数据对象 #print(user_obj.name, user_obj.id) # 此时还没创建对象呢,不信你打印一下id发现还是None #print(user_obj.name, user_obj.id) # 此时也依然还没创建 Session.add(user_obj) # 把要创建的数据对象添加到这个session里, 一会统一创建 Session.add(user_obj2) # 把要创建的数据对象添加到这个session里, 一会统一创建 Session.commit() # 现此才统一提交,创建数据View Code
效果:
mysql> select * from user; +----+-------------+----------+ | id | name | password | +----+-------------+----------+ | 1 | 王昭君 | 123456 | | 2 | 韩信 | 123456 | +----+-------------+----------+ 2 rows in set (0.00 sec)View Code
查找数据:
#Author:Yun import table_structure#导入表结构模块 from sqlalchemy.orm import sessionmaker Session_class = sessionmaker(bind=table_structure.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 Session = Session_class() # 生成session实例#cursor #查找所有数据 data1 = Session.query(table_structure.User).filter_by().all() #查找第一个数据 data2 = Session.query(table_structure.User).filter_by().first() #查找id=1的数据 data3= Session.query(table_structure.User).filter_by(id=1).all() #查找id=2的数据 data4 = Session.query(table_structure.User).filter(table_structure.User.id ==2).all() #查找id>1的所有数据 data5 = Session.query(table_structure.User).filter(table_structure.User.id>1).all() #多条件查询,id>0&id<2的数据 data6 = Session.query(table_structure.User).filter(table_structure.User.id>0).filter(table_structure.User.id<2).all() print(‘data1:‘,data1) print(‘data2:‘,data2) print(‘data3:‘,data3) print(‘data4:‘,data4) print(‘data5:‘,data5) print(‘data6:‘,data6)View Code
效果:
data1: [<1 name:王昭君>, <2 name:韩信>] data2: <1 name:王昭君> data3: [<1 name:王昭君>] data4: [<2 name:韩信>] data5: [<2 name:韩信>] data6: [<1 name:王昭君>]View Code
修改数据:
#Author:Yun #修改数据 import table_structure#导入表结构模块 from sqlalchemy.orm import sessionmaker Session_class = sessionmaker(bind=table_structure.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 Session = Session_class() # 生成session实例#cursor data = Session.query(table_structure.User).filter_by(name="王昭君").first()#修改数据 data.name = "妲己"#将王昭君修改为妲己 data.password = ‘654321‘ Session.commit()View Code
效果:
mysql> select * from user; +----+-------------+----------+ | id | name | password | +----+-------------+----------+ | 1 | 妲己 | 654321 | | 2 | 韩信 | 123456 | +----+-------------+----------+ 2 rows in set (0.00 sec)View Code
回滚:
#Author:Yun #回滚,类似于事物 import table_structure#导入表结构模块 from sqlalchemy.orm import sessionmaker Session_class = sessionmaker(bind=table_structure.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 Session = Session_class() # 生成session实例#cursor user_obj = table_structure.User(name="老夫子", password="123456") # 生成你要创建的数据对象 user_obj2 = table_structure.User(name="雅典娜", password="123456") # 生成你要创建的数据对象 Session.add(user_obj) # 把要创建的数据对象添加到这个session里, 一会统一创建 Session.add(user_obj2) # 把要创建的数据对象添加到这个session里, 一会统一创建 print(Session.query(table_structure.User.name).filter(table_structure.User.name.in_([‘老夫子‘,‘雅典娜‘])).all()) print(‘--------------after rollback---------------:‘) Session.rollback() print(Session.query(table_structure.User.name).filter(table_structure.User.name.in_([‘老夫子‘,‘雅典娜‘])).all()) Session.commit()#现在才统一提交修改数据View Code
效果:
[(‘老夫子‘,), (‘雅典娜‘,)] --------------after rollback---------------: []View Code
删除数据:
#Author:Yun #删除数据 import table_structure#导入表结构模块 from sqlalchemy.orm import sessionmaker Session_class = sessionmaker(bind=table_structure.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 Session = Session_class() # 生成session实例#cursor data = Session.query(table_structure.User).filter_by(name="妲己").first()#获取数据 Session.delete(data)#删除数据 Session.commit()View Code
效果:
mysql> select * from user; +----+-------------+----------+ | id | name | password | +----+-------------+----------+ | 2 | 韩信 | 123456 | +----+-------------+----------+ 1 rows in set (0.00 sec)View Code
统计和分组:
#Author:Yun import table_structure#导入表结构模块 from sqlalchemy.orm import sessionmaker Session_class = sessionmaker(bind=table_structure.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 Session = Session_class() # 生成session实例#cursor print(Session.query(table_structure.User).filter(table_structure.User.name.in_([‘韩信‘])).count())#mysql 默认大小写是一样的,如 ‘hello‘==‘HELLO‘ Session.commit()#现在才统一提交修改数据统计
效果:
1View Code
分组:
#Author:Yun #统计 import table_structure#导入表结构模块 from sqlalchemy.orm import sessionmaker Session_class = sessionmaker(bind=table_structure.engine) # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例 Session = Session_class() # 生成session实例#cursor from sqlalchemy import func print(Session.query(table_structure.User.name,func.count(table_structure.User.name)).group_by(table_structure.User.name).all()) Session.commit()#现在才统一提交修改数据View Code
效果:
[(‘韩信‘, 1)]View Code
外键关联: