python爬虫SQLAlchemy的数据存储操作

ORM的全称是:Object Relational Mapping (对象 关系 映射)
简单的说,orm是通过使用描述对象和数据之间映射的元数据,将程序中的对象自动持久化到关系数据库中。
ORM需要解决的问题是,能否把对象的数据直接保存到数据库中,又能否直接从数据库中拿到一个对象?要想做到上面两点,则必须要有映射关系。

ORM的优缺点
优点:

  • 提高开发效率
  • 在一个地方编写数据模型,就可以更轻松地更新,维护和重用代码。
  • 它迫使您编写MVC代码,最终使您的代码更简洁。
  • 不必编写格式不好的SQL(大多数Web程序员确实很讨厌它,因为SQL被视为一种“子”语言,而实际上却是一种非常强大和复杂的语言)。
  • 使用准备好的语句或事务就像调用方法一样简单。

缺点:

  • orm会牺牲程序的执行效率和会固定思维模式,在从系统结构上来看,采用orm的系统多是多层系统的,系统的层次太多,效率就会降低。
  • orm是一种完全面向对象的做法,所以面向对象的做法也会对性能产生一定的影响。
  • orm不是轻量级的工具;它不是功能强大的工具。 您必须进行设置。
  • 对于常规查询而言,性能还可以,但是对于大型项目,SQL管理员始终可以使用自己的SQL来做得更好。

常用的ORM

  • Java:Hibernate。
  • PHP:Propel或Doctrine
  • Python:Django ORM或SQLAlchemy(推荐)
  • C#:NHibernate或实体框架

如果要在Web编程中尝试ORM库,最好使用完整的框架堆栈,例如:

  • Symfony(PHP,使用Propel或Doctrine)
  • Django(Python,使用内部ORM)
SQLAlchemy:

sqlalchemy中文文档:
https://www.osgeo.cn/sqlalchemy/orm/tutorial.html
sqlalchemy官方文档:
https://docs.sqlalchemy.org/en/14/
在Python中,最有名的ORM框架是SQLAlchemy,比Django自带的ORM要好那么一点点。

常用的SQLAlchemy字段类型

模型字段类型名python中数据类型说明
Integerint普通整数,一般是32位
SmallIntegerint取值范围小的整数,一般是16位
BigIntegerint或long不限制精度的整数
Floatfloat浮点数
Numericdecimal.Decimal普通数值,一般是32位
Stringstr变长字符串
Textstr变长字符串,对较长或不限长度的字符串做了优化
LongTextstr长文本类型
Unicodeunicode变长Unicode字符串
UnicodeTextunicode变长Unicode字符串,对较长或不限长度的字符串做了优化
Booleanbool布尔值
Datedatetime.date日期
Timedatetime.time时间
DateTimedatetime.datetime日期和时间
DECIMALdecimal.Decimal定点类型
Enumstr枚举类型

常用的SQLAlchemy列约束选项

选项名说明
primary_key如果为True,代表表的主键
unique如果为True,代表这列不允许出现重复的值
index如果为True,为这列创建索引,提高查询效率
nullable如果为True,允许有空值,如果为False,不允许有空值
default为这列定义默认值
autoincrement是否自动增长
onupdate更新的时候执行的函数
name该属性在数据库中的字段映射

query可用参数:

  1. 模型对象。指定查找这个模型中所有的对象。
  2. 模型中的属性。可以指定只查找某个模型的其中几个属性。
  3. 聚合函数:
选项名说明
func.count统计行的数量
func.avg求平均值
func.max求最大值
func.min求最小值
func.sum求和

过滤方法:

过滤是数据 提取的一个很重要的功能,以下对一些常用的过滤条件进行详解,并且这些过滤条件都是只能通过filter方法实现的:

  1. equals 等于:
query.filter(User.name == 'ed')
  1. not equals 不等于:
query.filter(User.name != 'ed')
  1. like 模糊查询:
query.filter(User.name.like('%ed%'))
  1. in …在…里:
query.filter(User.name.in_(['ed','wendy','jack']))
#同时
query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%ed%'))))
  1. not in …不在…里:
query.filter(~User.name.in_('ed','wendy','jack'))
  1. is null 为空:
query.filter(User.name==None)

query.filter(User.name.is_(None))
  1. is not null 不为空:
query.filter(User.name != None)

query.filter(User.name.isnot(None)
  1. and 与:
from sqlalchemy import and_

query.filter(and_(User.name=='ed', User.fullname=='Ed Jones'))
# 或者
query.filter(User.name=='ed', User.fullname=='Ed Jones')
# 或者
query.filter(User.name=='ed',).filter(User.fullname=='Ed Jones')
  1. or 或:
from sqlalchemy import or_ 
query.filter(or_(User.name='ed', User.name='wendy'))

数据库基本操作

  • 在Flask-SQLAlchemy中,添加、修改、删除操作,均由数据库会话管理。
    • 会话用 db.session 表示。在准备把数据写入数据库前,要先将数据添加到会话中然后调用 db.commit() 方法提交会话。
  • 在 Flask-SQLAlchemy 中,查询操作是通过 query 对象操作数据。
    • 最基本的查询是返回表中所有数据,可以通过过滤器进行更精确的数据库查询。
问题简述:

1.要爬一个小说网站将文本存在数据库里

代码模块:
通过pip安装SQLAlchemy:

pip install sqlalchemy

导入模块 创建表对象模块代码:

from sqlalchemy import Column, String, create_engine, Integer, Text, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
# relationship两个表之间的外键关系
from sqlalchemy.ext.declarative import declarative_base

# 创建对象的基类:
Base = declarative_base()

# 定义Book对象
class Book(Base):
	# 定义数据库表名
    __tablename__  = 'b_data'

	# 表的结构 参数参照上面表单
    id = Column(Integer, primary_key=True, comment='主键ID')
    img_name = Column(String(50), comment="书封面")
    book_name = Column(String(50), comment='书名')
    author = Column(String(50), comment='作者名')
    book_type = Column(String(50), comment='小说类型')
    book_byte = Column(String(255), comment='小说字数')
    brief_introduction = Column(String(255), comment='小说简介')
    books_text = relationship('Book_text', backref='b_data') # relationship两个表之间的外键关系
    def __repr__(self):
        return self.book_name
    # __repr__() 是一个非常特殊的方法,它是一个“自我描述”的方法,该方法通常用于实现这样一个功能:当程序员直接打印该对象时,系统将会输出该对象的“自我描述”信息,用来告诉外界该对象具有的状态信息。

# 定义Book_text对象
class Book_text(Base):
    __tablename__ = 'b_text'
    id = Column(Integer(), primary_key=True, comment='主键ID')
    book_chapter = Column(String(50), comment='章节名')
    chapter_text = Column(Text(), comment='章节内容')
    book_data_id = Column(Integer,ForeignKey('b_data.id'))

# 初始化数据库连接:
engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/books', echo=True)

# 创建一个会话
Session = sessionmaker(bind=engine)
# 创建session对象:
session = Session()




aaa = '白帝,武帝'
# 添加一条数据到数据库
new_page = Book_text(book_chapter='境界划分', chapter_text=aaa,book_data_id=1)
# 添加到session:
session.add(new_page)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()

# 查询一条数据:
a = session.query(Book_text).get(1)
print(a)
# 查询 a 的chapter_text 里的数据
print(a.chapter_text)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值