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