SQLAlchemy 操作数据库

SQLAlchemy 操作数据库

SQLAlchemy为Python提供了不同数据库的统一接口,采用ORM的方式操作数据库,简洁优雅

一、安装

直接通过pip安装即可

pip install sqlalchemy

二、连接数据库

这里用小巧的sqlite来做测试

from sqlalchemy import create_engine# 创建连接引擎,这里的engine是lazy模式创建,直到第一次被使用才真实创建
# echo=True表示会用logger的方式打印传到数据库的SQL
engine = create_engine('sqlite:///./test.db', echo=True)

其他数据库连接方法,格式如下:

数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名
# 1.1 sqlite内存
engine = create_engine('sqlite:///:memory:', echo=True)
# 1.2 sqlite文件
engine = create_engine('sqlite:///./test.db', echo=True)# 2.1 MySQL default
engine = create_engine('mysql://user:passwd@localhost/mydatabase')
# 2.2 mysql-python
engine = create_engine('mysql+mysqldb://user:passwd@localhost/mydatabase')
# 2.3 MySQL-connector-python
engine = create_engine('mysql+mysqlconnector://user:passwd@localhost/mydatabase')
# 2.4 OurSQL
engine = create_engine('mysql+oursql://user:passwd@localhost/mydatabase')# 3.1 PostgreSQL default
engine = create_engine('postgresql://user:passwd@localhost/mydatabase')
# 3.2 psycopg2
engine = create_engine('postgresql+psycopg2://user:passwd@localhost/mydatabase')
# 3.3 pg8000
engine = create_engine('postgresql+pg8000://user:passwd@localhost/mydatabase')# 4.1 Oracle default
engine = create_engine('oracle://user:passwd@127.0.0.1:1521/mydatabase')
# 4.2 cx_oracle
engine = create_engine('oracle+cx_oracle://user:passwd@mydatabase')# 5.1 MS SQL pyodbc
engine = create_engine('mssql+pyodbc://user:passwd@mydatabase')
# 5.2 pymssql
engine = create_engine('mssql+pymssql://user:passwd@hostname:port/dbname')

可以看到,SQLAlchemy把数据库的连接和数据库的操作分离开来,向上提供统一接口

三、表结构

ORM中,表格对应一个类,所有类都要继承自Base基类

from sqlalchemy.ext.declarative import declarative_base# 基类
Base = declarative_base()# 定义User对象
class User(Base):"""Users table"""# 表的名字__tablename__ = 'users'__table_args__ = {'sqlite_autoincrement': True}# 表结构id = Column(Integer, primary_key=True, autoincrement=True)name = Column(String(32), nullable=False)age = Column(Integer, default=0)password = Column(String(64), unique=True)

四、操作

操作需要通过session来进行,增删改结束后,需要commit,查询不用

# 删除
session = DBSession()
duser = session.query(User).filter(User.id==2).delete()
session.commit()
session.close()#查询
session = DBSession()
quser = session.query(User).filter(User.id==4).one()
print('name:',quser.name)
session.close()

操作体验和很多ORM一致

五、完整测试代码

参考http://www.itfanr.cc/2017/01/06/use-sqlalchemy-by-python/

# coding=utf-8from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker# 创建连接引擎
# echo=True表示会用logger的方式打印传到数据库的SQL
engine = create_engine('sqlite:///./test.db', echo=True)# 表格对象基类
Base = declarative_base()# 创建会话的类
DBSession = sessionmaker(bind=engine)# 表格类
class User(Base):"""User table"""__tablename__ = 'users'  # 表名__table_args__ = {'sqlite_autoincrement': True}# 表结构id = Column(Integer, primary_key=True, autoincrement=True)name = Column(String(32), nullable=False)  # 有些数据库允许不指定String的长度age = Column(Integer, default=0)password = Column(String(64), unique=True)class Blog(Base):"""docstring for Blog"""__tablename__ = 'blogs'id = Column(Integer, primary_key=True)title = Column(String(100))desc = Column(String(500))class Tips(Base):"""docstring for tips"""__tablename__ = 'tips'id = Column(Integer, primary_key=True)name = Column(String(32))# 新增一条记录数据
def new_user():# 创建会话对象session = DBSession()new_user = User(name='Jery',password='123')session.add(new_user)  # 只是添加在session中,没有写到数据库session.commit()session.close()# 新增多条数据
def add_more_user():session = DBSession()session.add_all([User(name='guanyu', age=4, password='11111'),User(name='zhangfei', password='2233'),User(name='zhenji', password='44556')])session.commit()session.close()# 新增数据含中文,只要用unicode的字符即可
def add_user_for_zh():session = DBSession()new_user = User(name=u'关羽', password='12322233')session.add(new_user)session.commit()session.close()# 查询
def query_user():session = DBSession()q_user = session.query(User).filter(User.id == 4).one()  # one表示结果有且仅有一个print('name', q_user.name)session.close()  # 查询不用commit,如果不commit,会自动执行rollback#
def delete_user():session = DBSession()deleted_num = session.query(User).filter(User.id > 3).delete()print(deleted_num)session.commit()session.close()# c测试
def test_user():session = DBSession()# merge方法,如果存在就修改,不存在就插入(只判断主键,不判断unique列)t1 = session.query(User).filter(User.name == 'Jery').first()t1.age = 34session.merge(t1)session.commit()# 获取第2-3项users = session.query(User)[1:3]for u in users:print(u.name)session.close()# 执行sql语句
def sql_user():s = DBSession()# 不能用 `?` 的方式来传递参数 要用 `:param` 的形式来指定参数# s.execute('INSERT INTO users (name, age, password) VALUES (?, ?, ?)',('bigpang',2,'1122121'))# 这样执行报错# s.execute('INSERT INTO users (name, age, password) VALUES (:aa, :bb, :cc)',({'aa':'bigpang2','bb':22,'cc':'998'}))# s.commit()# 这样执行成功res = s.execute('select * from users where age=:aaa', {'aaa': 4})# print(res['name'])  # 错误# print(res.name)    # 错误# print(type(res))   # 错误for r in res:print(r['name'])s.close()# 执行sql语句
def sql_user2():# **传统 connection方式**# 创建一个connection对象,使用方法与调用python自带的sqlite使用方式类似# 使用with 来创建 conn,不需要显示执行关闭连接# with engine.connect() as conn:#  res=conn.execute('select * from users')#  data=res.fetchone()#  print('user is %s' %data[1])# 与python自带的sqlite不同,这里不需要 cursor 光标,执行sql语句不需要commit。如果是增删改,则直接生效,也不需要commit.# **传统 connection 事务**with engine.connect() as conn:trans = conn.begin()try:r1 = conn.execute("select * from users")print(r1.fetchone())r2 = conn.execute("insert into users (name,age,password) values (?,?,?)", ('tang', 5, '133444'))print(r2)trans.commit()except:trans.rollback()raise# **session**session = DBSession()session.execute('select * from users')session.execute('insert into users (name,age,password) values (:name,:age,:password)',{"name": 'dayuzhishui', 'age': 6, 'password': '887'})# 注意参数使用dict,并在sql语句中使用:key占位# 如果是增删改,需要 commitsession.commit()# 用完记得关闭,也可以用 withsession.close()if __name__ == "__main__":# 删除全部数据库Base.metadata.drop_all(engine)# 创建表格,如果已经存在,则不创建Base.metadata.create_all(engine)# 删除指定的表格Blog.__table__.drop(engine)# 新增数据new_user()# 新增多条数据add_more_user()# 新增数据含中文add_user_for_zh()# 查询query_user()# 删除delete_user()# 测试test_user()# 直接执行SQLsql_user()sql_user2()

用pycharm运行后的结构

1146398-20180912124149083-498637471.png

六、小结

之前遇到过的ORM一般用在web场景,SQLAlchemy作为一个独立组件而存在,让我眼前一亮。同时它也十分优雅,既可以使用ORM映射,在必要的场合还可以直接运行SQL,可谓数据处理的利器。

转载于:https://www.cnblogs.com/fanghao/p/9634173.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

贝塞尔曲线理解与应用

贝塞尔曲线并非是由贝塞尔发明的,但是是因为他把这个东西应用到当时的汽车领域而闻名的,所以取名为贝塞尔曲线。 在我看来,用简单的话来理解一下贝塞尔曲线,他是通过少量几个点,使用一套公式,生成一条平滑曲…

云服务器布置_【阿里云ECS】(一)云服务器上安装RStudio-server

【阿里云ECS】(一)云服务器上安装RStudio-server最近注册了阿里云个人版,打算研究研究shiny部署问题。进了阿里云ECS因为是Ubuntu16.04的对于安装R和RStudio还是要学习实践一下的。第一步,安装R语言。我们使用apt的方式进行安装,步…

H5前期知识点总结 9月12日

知识点补充: 属性继承例子,color、font(font-size/style/family/weight) 1、浏览器的默认字体大小是16px,谷歌浏览器的最小字体是10px,其他浏览器的最小字体是12px。 2、通配符选择器 “*”,即选中body里所有的标签。 …

Spring MVC:Ajax和JQuery

今天,我想演示如何将AJAX集成到Spring MVC应用程序中。 我将在客户端使用JQuery来发送请求和接收响应。 本教程将基于我以前关于Spring MVC和REST服务的教程之一。 在本文中,您将了解如何在异步请求的帮助下使Web应用程序更具交互性。 准备工作 我需要通…

手把手带你写一个JavaScript类型判断小工具

业务写了很多,依然不是前端大神,我相信这是很多‘入坑’前端开发同学的迷茫之处,个人觉得前端职业发展是有路径可寻的,前期写业务是一个积累过程,后期提炼总结,比如编程思想,父子类的原型继承&a…

yolov3之pytorch源码解析_springmvc源码架构解析之view

说在前面前期回顾sharding-jdbc源码解析 更新完毕spring源码解析 更新完毕spring-mvc源码解析 更新完毕spring-tx源码解析 更新完毕spring-boot源码解析 更新完毕rocketmq源码解析 更新完毕dubbbo源码解析 更新完毕netty源码解析 更新完毕spring源码架构更新完毕springmvc源码架…

Xstream将XML转换为javabean的问题

1.问题:Xstream is not security 解决方法:加上 2.问题:如果没有第二行代码,会出现xstream forbiddenclassexception 解决方法:加上第二行,其中参数是要进行解析的对象! 调用该方法:…

蚂蚁属性细微差别

每隔一段时间,我会想起Ant属性的一些细微差别 ,一旦忘记它们,在与Ant交互时会引起混乱。 特别是, Ant属性 通常是不可变的 (不包括Ant 1.8版本的 局部属性 ),并且在其首次设置时“永久”设置&am…

《从零构建前后分离的web项目》准备 - 前端了解过关了吗?

前端基础架构和硬核介绍 技术栈的选择 首先我们构建前端架构需要对前端生态圈有一切了解,并且最好带有一定的技术前瞻性,好的技术架构可能日后会方便的扩展,减少重构的次数,即使重构也不需要大动干戈,我通常选型技术栈…

联想w540笔记本参数_2020年12月笔记本电脑推荐!联想、惠普、华为笔记本电脑推荐!18款高性价比笔记本电脑推荐!!!...

前言&#xff1a;笔记本电脑&#xff0c;主要分为三种&#xff1a;轻薄本<全能本<游戏本。轻薄本&#xff0c;又称办公笔记本电脑&#xff0c;因为轻薄方便携带&#xff0c;通常用于移动办公使用。全能本&#xff0c;就是把轻薄本的集显变成了小独显&#xff0c;增加了独…

【BZOJ 1098】办公楼(补图连通块个数,Bfs)

补图连通块个数这大概是一个套路吧&#xff0c;我之前没有见到过&#xff0c;想了好久都没有想出来QaQ 事实上这个做法本身就是一个朴素算法&#xff0c;但进行巧妙的实现&#xff0c;就可以分析出它的上界不会超过 $O(n m)$。 接下来介绍一下这个技巧&#xff1a; 很显然一个…

Spring MVC:资源

我从博客读者那里收到的最常见的问题之一是如何在Spring MVC的应用程序中使用CSS和javascript文件。 因此&#xff0c;这是撰写有关Spring MVC中资源使用情况的文章的好机会。 通常&#xff0c;我将使用基于Java的配置方法。 如今&#xff0c;很难想象没有CSS和JavaScript文件…

c语言读文件空格间隔,c语言文件流实现按单个词读取(以空格、分号等作间隔)...

c语言文件流实现按词读取(以空格、分号等作间隔)1.基本描述在之前的作业中&#xff0c;认真编写代码&#xff0c;从中发现不少知识积累上的欠缺。编程中使用到的c语言文件读取&#xff0c;要求是按照获取到一个完整的词&#xff0c;并对其进行处理。写有java或c语言源程序的.tx…

山东专升本access知识点_全国各省份每年的专升本考试大纲啥时候公布?考纲公布之前你该做什么?...

?星标/置顶专升本招考下一个上岸的就是你最近小编在专升本招考后台收到很多同学的留言&#xff0c;大多同学都是看到好多省都公布了专升本考试政策和大纲&#xff0c;却迟迟不见自己所在的省份出&#xff0c;于是火急火燎地找到小编来问&#xff1a;XX省的考试大纲到底啥时候出…

观点|蚂蚁金服玉伯:我们是如何从前端技术进化到体验科技的?

小蚂蚁说&#xff1a;王保平&#xff0c;花名玉伯。熟悉前端和SeaJS的人一定对这个名字不陌生。作为前端领域的一枚大大大牛&#xff0c;他现在担任蚂蚁金服体验技术部负责人。本文&#xff0c;他分享了他从前端一路进阶升级到体验科技的个人思考&#xff0c;并详细介绍了体验科…

excel 电阻并联计算_电路分析基础(5)-关于电阻,有些话我还是要说一说

电阻定义&#xff1a;导体对电流的阻碍作用就叫该导体的电阻。不同的导体&#xff0c;电阻一般不同&#xff0c;电阻是导体本身的一种性质。定义式如下&#xff1a;因此&#xff0c;我们应该清楚了欧姆定律的本质到底是什么&#xff0c;为啥电阻跟电压和电流没有关系&#xff0…

针对新手的Java EE7和Maven项目–第2部分–为我们的应用程序定义一场简单的战争...

从第一部分恢复 第1部分 我们刚刚定义了父 pom。 一种特殊的pom类型&#xff0c;它最终定义了我们的应用程序将要使用的库。 它还配置了所有用于打包我们应用程序每个模块的Maven工具。 您可以在此处 签出 -1部分示例代码。 因此&#xff0c;到目前为止&#xff0c;在将要开发…

postman实现从response headers中获取cookie,并将其设置为环境变量

1.最近在学习postman的使用方法,为了保证后续模块操作&#xff0c;必须在登录时获取的session值&#xff0c;并将其设置为环境变量&#xff0c;session的位置处于response headers里面返回的set-cookie参数&#xff0c;并且将set-cookie中的session通过split方法截取出来. 写法…

010 pandas的DataFrame

一&#xff1a;创建 1.通过二维数组进行创建 2.取值 取列,取位置的值 3.切片取值 这个和上面的有些不同&#xff0c;这里先取行&#xff0c;再取列 4.设定列索引 这里使用的行索引与上面不同。 5.通过字典的方式创建 6.索引 包含行索引&#xff0c;与列索引 7.修改列索引 转载于…

unity烘培单个物体_Unity可编程渲染管线(SRP)教程:二、自定义着色器

本文翻译自Catlike Coding&#xff0c;原作者&#xff1a;Jasper Flick。本文经原作者授权&#xff0c;转载请说明出处。原文链接在下&#xff1a;https://catlikecoding.com/unity/tutorials/scriptable-render-pipeline/custom-shaders/​catlikecoding.com本章内容如下&…