【Scrapy SQLalchemy 基于orm的框架】基本的使用实例

        sqlalchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。

        下边是基本的操作实例:

sqlalchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。
SQLAlchemy操作数据库
#1.连接数据库,mysql指明数据库系统类型,pymysql是连接数据库接口的模块,root是数据库系统用户名,后边跟的是数据库系统密码,
engine=create_engine("
    #pymysql
#mysql+pymysql://:@/[?]
    mysql+pymysql://root:****@localhost:3306/pymysql_demo?
    #对数据库进行编码设置,能对数据库进行中文读写
    charset=utf8", 
    #pool_size用于设置连接数,默认设置5个
    pool_size=5, 
    #erflow默认连接数为10。当超出最大连接数后,如果超出的连接数在max_overflow设置的访问内,超出部分可以继续连接访问,
    max_overflow=4, 
    #pool_recycle: 连接重置周期,默认为-1,推荐设置为7200,即如果连接已空闲7200秒,就自动重新获取,防止connection被关闭
    pool_recycle=7200, 
    #pool_timeout:连接超时时间,默认为30秒,超过时间的连接会连接失败
    pool_timeout=30)
#创建数据表
# 创建映射数据库表类,列名对应数据库列名
# 字段,属性
class table1(Base):
    # 指定表名
    __tablename__ = 'table1'
    id = Column(INTEGER, primary_key=True)
    name = Column(String(50))
    age = Column(INTEGER)
# 在数据库中创建数据表
Base.metadata.create_all(engine)
#增
Base = declarative_base()
# 引入sessionmaker模块,指明绑定已连接的engin对象,生成会话对象session,该对象用于数据库的增删改查
# 可以把 sessionmaker 想象成一个手机,engine 当做 MySQL 的号码,
# 拨通这个“号码”我们就创建了一个 Session 类,下面就可以通过这个类的实例与 MySQL 愉快的交谈了!
DBsession = sessionmaker(bind=engine)
session = DBsession()
# 添加数据,新建对象,传入数据
new_data1 = table1(id=9, name='sd', age=10)
# 将新建对象加入数据库,调用 session.add() 添加一个,或者 session.add_all() 一次添加多个,以列表形式添加
session.add(new_data)
#删
session.query(table1).filter_by(id=10).delete()
#改
# 更新数据,先查询表id为8的数据,然后update对这条数据进行更新,update数据的格式是字典类型
# filter_by相当于SQL语句里的where条件, 不能填> < 号print(session.query(table1).filter_by(id=8).update({table1.age: 11}))
# 使用filter判断条件较为灵活
print(session.query(table1).filter(table1.id > 8).update({table1.age: 11}))
# 提交事务,增删改才需要执行这条命令
session.commit()
# 关闭会话,不是必要的,但最好加上
session.close()

#查
# 查询所有数据
get_data = session.query(table1).all()
print(type(get_data))  # list
for i in get_data:
    print('名字:' + i.name)
    print('年龄:%d' % i.age)
# 查询某一字段select name from table1
get_data = session.query(table1.name).all()
for i in get_data:
    print('名字:'+i.name)
# 根据条件查询某条数据
# 方法1:
get_data = session.query(table1).filter(table1.id == 2).all()
# 方法2:
get_data = session.query(table1).filter_by(id=20).all()
if get_data == []:
    print('=')
print('数据类型是:' + str(type(get_data))) 返回值为一个列表
for i in get_data:
    print('名字:'+i.name)
print('年龄:'+i.age)
# 多条件筛选select * from table1 where id>1 and age >5
get_data = session.query(table1).filter(table1.id > 1, table1.age > 5).all()
print(type(get_data))
for i in get_data:
    print('名字:'+i.name)
    print('年龄:%d'%i.age)

#ORM:ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。 正确使用ORM的前提是了解关系数据库的原理。 ORM就是把数据库表的行与相应的对象建立关联,互相转换。 由于关系数据库的多个表还可以用外键实现一对多、多对多等关联,相应地, ORM框架也可以提供两个对象之间的一对多、多对多等功能
#1.创建表
create_engine方法参数('使用数据库+数据库链接模块://数据库用户名:密码@ip地址:端口/要连接的数据库名称?charset=utf8',echo=True表示是否查看生成的sql语句,max_overflow=5)
max_overflow=5 表示最大连接数

declarative_base()创建一个SQLORM基类
Column()设置字段属性
create_all()向数据库创建指定表

创建表数据类型

整数型:TINYINT,SMALLINT,INT,BIGINT
Boolean()对应TINYINT
Integer()对应INT
SMALLINT()对应SMALLINT
BIGINT()对应BIGINT

浮点型:FLOAT,DOUBLE,DECIMAL(M,D)
DECIMAL()对应DECIMAL
Float()对应FLOAT
REAL()对应DOUBLE

字符型:CHAR,VARCHAR
String(40)对应VARCHAR
CHAR()对应CHAR

日期型:DATETIME,DATE,TIMESTAMP
DATETIME()对应DATETIME
DATE()对应DATE
TIMESTAMP()对应TIMESTAMP

备注型:TINYTEXT,TEXT,
Text()对应TEXT
UnicodeText(10)对应TINYTEXT

##############################################################################

# -*- coding:utf-8 -*-

import sqlalchemy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine
#利用pypymysql或者mysqlconnector插件来调用数据库API
engine = create_engine("mysql+mysqlconnector://root:[email protected]:3306/project_db", echo=True)

#declarative_base()创建一个SQLORM基类
Base = declarative_base()
#括号内就是定义的Base
class People(Base):
    __tablename__ = "people" # 表名
    #Column()设置字段属性
    #primary_key=True主键索引,autoincrement=True自增字段
    id = Column(Integer, primary_key=True, autoincrement=True)
    #nullable=False类容不能为空
    name = Column(String(16), nullable=False)
    age = Column(Integer, nullable=False)
    job = Column(String(16), nullable=False)
    salary = Column(Integer, nullable=False)
    
#create_all()向数据库创建指定表
Base.metadata.create_all(engine)  # 新建表
参考网址:http://ddrv.cn/a/380894
一个完整的实例代码:https://blog.csdn.net/weixin_45387160/article/details/103898251

这里千万要注意的是当你使用的时候,文件名不要写成库的名字,下边是一个基本的实例,用来在mysql中创建一个表

import sys

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine

engine=create_engine("mysql+pymysql://root:root@localhost:3306/aa",
    #对数据库进行编码设置,能对数据库进行中文读写
#    charset="utf8", 
#    #pool_size用于设置连接数,默认设置5个
#    pool_size=5, 
#    #erflow默认连接数为10。当超出最大连接数后,如果超出的连接数在max_overflow设置的访问内,超出部分可以继续连接访问,
    max_overflow=4, 
#    #pool_recycle: 连接重置周期,默认为-1,推荐设置为7200,即如果连接已空闲7200秒,就自动重新获取,防止connection被关闭
#    pool_recycle=7200, 
#    #pool_timeout:连接超时时间,默认为30秒,超过时间的连接会连接失败
#    pool_timeout=30
    )
Base = declarative_base()
class table1(Base):
    # 指定表名
    __tablename__ = 'table1'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    age = Column(Integer)
# 在数据库中创建数据表
Base.metadata.create_all(engine)

接下来介绍的从ORM基类转到对象该怎么操作。

#新的教程:如何来初始化导入SQLAlchemy ,并初始化DBSession
#一共有四个步骤
#第一步引入:
# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

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

#第三步定义对象:
# 定义User对象:
class User(Base):
    # 表的名字:
    __tablename__ = 'user'

    # 表的结构:
    id = Column(String(20), primary_key=True)
    name = Column(String(20))

# 第四步初始化数据库连接:
# 初始化数据库连接:
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')

# 第五步创建DBSession
DBSession = sessionmaker(bind=engine)

#第5步有了基类以后(另一种说法就是ORM),就开始面向对象,并操作它。
#第六步操作数据库
# 创建session对象:
session = DBSession()
# 创建新User对象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()

#第六步可以参考上边的操作,不用基类来操作,曲边在于对象操作相对于来说更安全。session相当于一个有orm数据库模型的数据库连接

#与第六步同步的操作是查询数据库,实例代码如下:
session = DBSession()
# 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
user = session.query(User).filter(User.id=='5').one()
# 打印类型和对象的name属性:
print('type:', type(user))
print('name:', user.name)

这里是参考最佳学习网站廖雪峰的官网:https://www.liaoxuefeng.com/wiki/897692888725344/955081460091040

还有https://www.jianshu.com/p/20593da77c04

接下来要演示的是该框架在scrapy框架中的pipeline.py管道文件中是怎么使用的。

#这里是引入sqlalchemy的测试
import sqlalchemy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine

Base=declarative_base()
class Lagoujob(Base): #这个参数父类名
    __tablename__='lagoujob' #存储岗位基本信息的数据表
    id=Column(Integer,primary_key=True)
    area=Column(String(50))
    community=Column(String(50))
    village=Column(String(50))
    price=Column(String(100))
#自定义的orm处理对象函数
class ormSQLalchemyPipeline(object):
    """保存文章到数据库"""
    def __init__(self):
        engine=create_engine("mysql+pymysql://root:root@localhost:3306/aa",max_overflow=4)
        Base.metadata.create_all(engine)
        self.DBSession = sessionmaker(bind=engine)
    def open_spider(self, spider):
        """This method is called when the spider is opened."""
        pass

    def process_item(self, item, spider):
        print(len(item['area']))
        session = self.DBSession()
#        new_user = Lagoujob(area='hhu', community='Bob',village='Bob',price='dfd')
#        session.add(new_user)
#        session.commit()
#        session.close()
        for i in range(len(item['area'])):
            a = Lagoujob(area=item["area"][i].encode("utf-8"),
                        community=item["Community"][i].encode("utf-8"),
                        village=item["village"][i].encode("utf-8"),
                        price=item["price"][i].encode("utf-8"))
            session.add(a)
            session.commit()
        session.close()

    def close_spider(self, spider):
        pass

记得千万在setting文件中激活。

下一步是模型的精简,众所周知,pipeline中定义的管道是有很多的,如果把orm的模型定义放在pipeline中的话会造成一种结构上的絮乱。最好的方法是把sqlalchemy关于有自主部分的连接给存入到一个单独的model中。

首先建立一个model.py文件,如下;

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
Topic: 定义数据库模型实体
Desc : 
"""
import datetime

from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String, Text, DateTime
#from coolscrapy.settings import DATABASE
#
def db_connect():
    return create_engine("mysql+pymysql://root:root@localhost:3306/aa",max_overflow=4)

def create_news_table(engine):
    """"""
    Base.metadata.create_all(engine)

def _get_date():
    return datetime.datetime.now()
Base = declarative_base()

class Lagoujob(Base): #这个参数父类名
    __tablename__='lagoujob' #存储岗位基本信息的数据表
    id=Column(Integer,primary_key=True)
    area=Column(String(50))
    community=Column(String(50))
    village=Column(String(50))
    price=Column(String(100))
#自定义的orm处理对象函数

然后在管道文件中上方引入这些东西

from LianjiaScrapy.models import db_connect, create_news_table, Lagoujob
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager

其中from contextlib import contextmanager这个引入是为了接下来的代码中使用了with函数,并且在函数中调用了自定义的代码,所以才需要引入上下文管理器。

下边是pipeline中的代码:

@contextmanager#就是这里下边的with中用到ession_scope这个函数,所以需要添加一个上下文管理对象。
def session_scope(Session):
    """Provide a transactional scope around a series of operations."""
    session = Session()
    session.expire_on_commit = False
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()

class EasayormSQLalchemyPipeline(object):
    """保存文章到数据库"""
    def __init__(self):
        engine = db_connect()
        create_news_table(engine)
        self.Session = sessionmaker(bind=engine)
    def open_spider(self, spider):
        """This method is called when the spider is opened."""
        pass
    def process_item(self, item, spider):
        for i in range(len(item['area'])):
            a = Lagoujob(area=item["area"][i].encode("utf-8"),
                        community=item["Community"][i].encode("utf-8"),
                        village=item["village"][i].encode("utf-8"),
                        price=item["price"][i].encode("utf-8"))
            with session_scope(self.Session) as session:
                session.add(a)
    def close_spider(self, spider):
        pass

 

你可能感兴趣的:(python)