一、ORM简介
1. 之前项目操作回顾:
- 存在的问题:
- 查询、删除操作略复杂
- 不能对数据库的值进行更进一步处理,例如对
title
的内容大写
- 解决思路:
- 将数据库的的值,看作一个对象,将其属性当作方法
- 当需要某属性操作时,可以单独调用
2. ORM的实现
对象关系映射ORM的四种实现方法:
- SqlObject
- peewee
- Django`s ORM
- SQLALchemy
二、 SQLALchemy
-
原理结构图
-
模型介绍
常见类型:- Interger 整型
- Float 浮点型
- Boolean 布尔型
- ForeignKey 外键(例如新闻与该新闻评论的关系)
- Date/DateTime 日期
- String
- …
-
新建模型( 完全按照帮助文档来 )
(1)创建连接: engine 就是数据库的一个连接# 先导包 from sqlalchemy import create_engine # 定义引擎 # mysql默认语法: engine = create_engine('mysql://user:passwd@localhost:port/dbname') # 举例说明 engine = create_engine('mysql://root@localhost:3306/news_test')
(2)声明映射、创建模型( 表对象 )
-
生成基类
# 导入方法 from sqlalchemy.ext.declarative import declarative_base # 生成基类 Base = declarative_base( )
- 继承基类,并定义表明、列名和列的类型
# 导入要使用的类型
from sqlalchemy import Column, Integer, String, DateTime, Boolean
# 定义表对象
class News(Base):
#定义表命
__tablename__ = 'news'
id = Column(Integer, primary_key=True)
title = Column(String(100), nullable=False)
types = Column(String(10), nullable=False)
content = Column(String(2000), nullable=False)
image = Column(String(300), )
author = Column(String(30), )
view_count = Column(Integer)
created_at = Column(DateTime)
is_valid = Column(Boolean)
-
元数据创建表
python命令行执行: 导入表对象News、导入引擎engine 创建表语法: 表对象.metadata.create_all( engine ) 即 News.metadata.create_all
- 新增数据
-
以面向对象编程思维
-
创建的数据库必须支持utf8,才可以正常显示中文
-
编写一个类 Class OrmTest(object):
(1)创建session会话导入sessionmaker包: from sqlalchemy.orm import sessionmaker 创建Session对象: Session = sessionmaker( bind=engine)
( 2 ) 初始化 函数,使得类中的session都是Session( )连接
def __init__(self): self.session = Session( )
( 3 ) 新增数据函数 add_one( )
def add_one(self): #使用表对象新增一条记录 news_object = News( ***** ) # 使用会话传递数据 self.session.add(news_object) # 提交 self.session,commit( ) # 如果成功,返回提交结果 return news_object
( 4 ) 运行:
主函数 main( )
创建OrmTest类对象
打印新增内容的iddef main( ): obj = OrmTest( ) rest = obj.add_one( ) print( rest.id )
( 5 ) 注意的问题
新增数据内容包含中文时报错,需要在设置engine时设定字符engine = engine = create_engine('mysql://root@localhost:3306/news_test?charset=utf8')
数据库创建时应设置与表相同的字符集
( 6 ) 扩展——增加多条记录
先创建记录
new1 = New( *** ) …新增多条语法:
self.session.add_all( [new1,new2,new3]) self.session.commit( )
-
查询数据
查询一条: def get_one(self): # get( )获取id为指定值的记录 return self.session.query(News).get(1) 查询多条: def get_more(self): # 过滤、排序 return self.session,query(News).filter_by(is_valid = True)
-
get( ) 用于主键的查询
-
filter( )的多种用法
-
filter_by( ) 与filter( )区别:
-filter_by
和filter
都是过滤条件,只是用法有区别filter_by
里面不能用!=
还有> <
等等,所有filter
用得更多,filter_by
只能用=
-
格式化打印多个参数:
print('ID:{0} => title:{1}'.format(new_object.id,new_object.title))
-
使用循环打印多条记录的值
def main():
rest = obj.get_more()
if rest:
print(rest.count())
for new_object in rest:
print('ID:{0} => title:{1}'.format(new_object.id, new_object.title))
else:
print("Not exist")
- 修改数据
- 修改数据是在查询到相关数据后进行
- 修改数据分为一条数据和多条数据,多条数据使用for循环
- 直接修改值
- 修改后一定记得commit( )提交事务
def update_data(self, pk):
''' 更新数据 '''
new_object = self.session.query(News).get(pk)
if new_object:
new_object.is_valid = 1
self.session.add(new_object)
self.session.commit()
return True
return False
7. 删除数据
- 类似与修改数据操作
- 查询获取数据后,进行删除操作
- 分为一条和多条删除,多条使用循环
- 调用 self.session.delete( new_object ) 进行删除
- 最后commit( )提交一下
def delete_data(self, pk):
new_object = self.session.query(News).filter(News.id > pk)
if new_object:
for item in new_object:
self.session.delete(item)
self.session.commit()
return True
return False