IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python:sqlalchemy-快速开始 -> 正文阅读

[Python知识库]python:sqlalchemy-快速开始

#

一、声明模型

首先我们定义了模块级结构,这些结构将形成我们将从数据库中查询的结构。这种结构称为?声明性映射,讲白了其实就是SQL表中存在的元数据。

from?sqlalchemy?import?Column
from?sqlalchemy?import?ForeignKey
from?sqlalchemy?import?Integer
from?sqlalchemy?import?String
from?sqlalchemy.orm?import?declarative_base
from?sqlalchemy.orm?import?relationship


Base?=?declarative_base()


class?User(Base):
????__tablename__?=?"user"
????id?=?Column(Integer,?primary_key=True)
????name?=?Column(String(30))
????fullname?=?Column(String)
????addresses?=?relationship(
????????"Address",?back_populates="user",?cascade="all,?delete-orphan"
????)

????def?__repr__(self):
????????return?f"User(id={self.id!r},?name={self.name!r},?fullname={self.fullname!r})"


class?Address(Base):
????__tablename__?=?"address"
????id?=?Column(Integer,?primary_key=True)
????email_address?=?Column(String,?nullable=False)
????user_id?=?Column(Integer,?ForeignKey("user.id"),?nullable=False)
????user?=?relationship("User",?back_populates="addresses")

????def?__repr__(self):
????????return?f"Address(id={self.id!r},?email_address={self.email_address!r})"

信息注释:

  • Column表示数据库表中的列。
  • primary_key设置字段为主键
  • ForeignKey设置字段为外键
  • nullable可为空,意思是可为空值
  • relationship提供两个映射类之间的关系
  • back_populates是指定和哪个类作映射关系
  • cascade级联,可理解意思就是主表数据被删除,关联的子表跟随操作

二、建立连接

from?sqlalchemy?import?create_engine


_SQLALCHEMY_DATABASE_URL?=?"mysql+pymysql://root:123456@192.168.0.110:3306/sqlalchemy_db"

engine?=?create_engine(
????#?echo=True参数表示连接发出的?SQL?将被记录到标准输出
????#?future=True是为了方便便我们充分利用sqlalchemy2.0样式用法
????_SQLALCHEMY_DATABASE_URL,?echo=True,?future=True
)

信息注释:

  • 这里就是定义一个连接数据库的变量
  • 调用creat_engine方法来连接指定的数据库

三、创建数据表

Base.metadata.create_all(engine)

信息注释:

  • 创建存储在此元数据中的所有表。
  • 默认情况下有条件,不会尝试重新创建目标数据库中已经存在的表。

注意点:

  • 如果你使用的是sqlite数据库,则直接运行代码就会自动根据定义的模型自动创建数据;如果你是mysql数据库,则需要自己先建好表,不然运行时会抛出数据表不存在的问题。

上述代码运行完成,在控制台就会产生一些日志,没有报错就表示成功了:

2022-05-01?13:35:53,251?INFO?sqlalchemy.engine.Engine?SELECT?DATABASE()
2022-05-01?13:35:53,251?INFO?sqlalchemy.engine.Engine?[raw?sql]?{}
2022-05-01?13:35:53,255?INFO?sqlalchemy.engine.Engine?SELECT?@@sql_mode
2022-05-01?13:35:53,255?INFO?sqlalchemy.engine.Engine?[raw?sql]?{}
2022-05-01?13:35:53,256?INFO?sqlalchemy.engine.Engine?SELECT?@@lower_case_table_names
2022-05-01?13:35:53,257?INFO?sqlalchemy.engine.Engine?[raw?sql]?{}
2022-05-01?13:35:53,260?INFO?sqlalchemy.engine.Engine?BEGIN?(implicit)
2022-05-01?13:35:53,260?INFO?sqlalchemy.engine.Engine?SELECT?COUNT(*)?FROM?information_schema.tables?WHERE?table_schema?=?%(table_schema)s?AND?table_name?=?%(table_name)s
2022-05-01?13:35:53,260?INFO?sqlalchemy.engine.Engine?[generated?in?0.00014s]?{'table_schema':?'sqlalchemy_db',?'table_name':?'user'}
2022-05-01?13:35:53,262?INFO?sqlalchemy.engine.Engine?SELECT?COUNT(*)?FROM?information_schema.tables?WHERE?table_schema?=?%(table_schema)s?AND?table_name?=?%(table_name)s
2022-05-01?13:35:53,263?INFO?sqlalchemy.engine.Engine?[cached?since?0.002399s?ago]?{'table_schema':?'sqlalchemy_db',?'table_name':?'address'}
2022-05-01?13:35:53,265?INFO?sqlalchemy.engine.Engine?COMMIT

Process?finished?with?exit?code?0

#

一、创建对象并持久化

现在准备往数据库中插入数据

  • 通过创建UserAddress对象的实例来实现这一点,这些对象具有init()声明性映射过程自动建立的方法。
  • 使用一个名为Session的对象将它们传递给数据库,该对象利用SessionEngine与数据库进行交互。
  • 使用Session.add_all()方法一次添加多个对象,该Session.commit()方法将用于刷新对数据库的任何未决更改,然后提交当前数据库事务,只要使用 ,该事务始终在进行中Session
from?sqlalchemy.orm?import?Session


with?Session(engine)?as?session:
????spongebob?=?User(
????????name="zhangsansan",
????????fullname="sansan",
????????addresses=[Address(email_address="sansan@sqlalchemy.com")],
????)
????sandy?=?User(
????????name="lixiaoxiao",
????????fullname="xiaoxiao",
????????addresses=[
????????????Address(email_address="xiaoxiao@sqlalchemy.com"),
????????????Address(email_address="dongdong@squirrelpower.com"),
????????],
????)
????patrick?=?User(name="lidongdong",?fullname="dongdong")
????session.add_all([spongebob,?sandy,?patrick])
????session.commit()

信息注释:

  • 这里使用的是上下文管理器的方式来插入数据,数据执行完成后,会自动执行关闭连接操作

上述代码执行完成数据插入后,在控制台就会产生一些日志,没有报错就表示成功了:

2022-05-01?14:43:26,282?INFO?sqlalchemy.engine.Engine?INSERT?INTO?user?(name,?fullname)?VALUES?(%(name)s,?%(fullname)s)
2022-05-01?14:43:26,282?INFO?sqlalchemy.engine.Engine?[generated?in?0.00015s]?{'name':?'zhangsansan',?'fullname':?'sansan'}
2022-05-01?14:43:26,285?INFO?sqlalchemy.engine.Engine?INSERT?INTO?user?(name,?fullname)?VALUES?(%(name)s,?%(fullname)s)
2022-05-01?14:43:26,286?INFO?sqlalchemy.engine.Engine?[cached?since?0.003192s?ago]?{'name':?'lixiaoxiao',?'fullname':?'xiaoxiao'}
2022-05-01?14:43:26,289?INFO?sqlalchemy.engine.Engine?INSERT?INTO?user?(name,?fullname)?VALUES?(%(name)s,?%(fullname)s)
2022-05-01?14:43:26,289?INFO?sqlalchemy.engine.Engine?[cached?since?0.006635s?ago]?{'name':?'lidongdong',?'fullname':?'dongdong'}
2022-05-01?14:43:26,293?INFO?sqlalchemy.engine.Engine?INSERT?INTO?address?(email_address,?user_id)?VALUES?(%(email_address)s,?%(user_id)s)
2022-05-01?14:43:26,293?INFO?sqlalchemy.engine.Engine?[generated?in?0.00025s]?{'email_address':?'sansan@sqlalchemy.com',?'user_id':?1}
2022-05-01?14:43:26,300?INFO?sqlalchemy.engine.Engine?INSERT?INTO?address?(email_address,?user_id)?VALUES?(%(email_address)s,?%(user_id)s)
2022-05-01?14:43:26,300?INFO?sqlalchemy.engine.Engine?[cached?since?0.007286s?ago]?{'email_address':?'xiaoxiao@sqlalchemy.com',?'user_id':?2}
2022-05-01?14:43:26,303?INFO?sqlalchemy.engine.Engine?INSERT?INTO?address?(email_address,?user_id)?VALUES?(%(email_address)s,?%(user_id)s)
2022-05-01?14:43:26,303?INFO?sqlalchemy.engine.Engine?[cached?since?0.009968s?ago]?{'email_address':?'dongdong@squirrelpower.com',?'user_id':?2}
2022-05-01?14:43:26,310?INFO?sqlalchemy.engine.Engine?COMMIT

Process?finished?with?exit?code?0

#

一、数据查询-简单的选择

from?sqlalchemy.orm?import?Session
from?sqlalchemy?import?select


session?=?Session(engine)

stmt?=?select(User).where(User.name.in_(["zhangsansan",?"lidongdong"]))
for?user?in?session.scalars(stmt):
????print(f"运行结果:{user}")

信息注释:

  • scalars是将标量筛选应用于结果上

运行结果:

2022-05-01?15:05:28,425?INFO?sqlalchemy.engine.Engine?SELECT?user.id,?user.name,?user.fullname?
FROM?user?
WHERE?user.name?IN?(%(name_1_1)s,?%(name_1_2)s)
2022-05-01?15:05:28,425?INFO?sqlalchemy.engine.Engine?[generated?in?0.00068s]?{'name_1_1':?'zhangsansan',?'name_1_2':?'lidongdong'}
运行结果:User(id=1,?name='zhangsansan',?fullname='sansan')
运行结果:User(id=3,?name='lidongdong',?fullname='dongdong')

从查询结果可以清晰看到符合条件的两条数据显示出来了,而且查询的SQL语句也体现出来了,是不是慢慢的感觉SQL语句的技能也提升了呢


二、数据查询-多表

from?sqlalchemy.orm?import?Session
from?sqlalchemy?import?select


session?=?Session(engine)

stmt?=?(
????select(Address).join(
????????Address.user
????).where(
????????User.name?==?"zhangsansan"
????).where(
????????Address.user_id?==?1
????)
)
sandy_address?=?session.scalars(stmt).one()
print(f"运行结果:{sandy_address}")

信息注释:
scalars是将标量筛选应用于结果上,one是拿一条结果

运行结果:

2022-05-01?15:10:13,712?INFO?sqlalchemy.engine.Engine?SELECT?address.id,?address.email_address,?address.user_id?
FROM?address?INNER?JOIN?user?ON?user.id?=?address.user_id?
WHERE?user.name?=?%(name_1)s?AND?address.user_id?=?%(user_id_1)s
2022-05-01?15:10:13,712?INFO?sqlalchemy.engine.Engine?[generated?in?0.00021s]?{'name_1':?'zhangsansan',?'user_id_1':?1}
运行结果:Address(id=1,?email_address='sansan@sqlalchemy.com')

从查询结果可以清晰看到符合条件的数据显示出来了,体现的SQL语句中也可以清晰看到,使用的就是JOIN关联查询。

#

一、数据更新

from?sqlalchemy.orm?import?Session
from?sqlalchemy?import?select


session?=?Session(engine)

stmt?=?select(User).where(User.name?==?"zhangsansan")
patrick?=?session.scalars(stmt).one()

stmt?=?(
????select(Address).join(
????????Address.user
????).where(
????????User.name?==?"lixiaoxiao"
????).where(
????????Address.user_id?==?2
????)
)
sandy_address?=?session.scalars(stmt).one()


#???进行更改-给用户再增加一个关联的邮箱地址
patrick.addresses.append(
????Address(email_address="sansan@163.com")
)

#???进行更改-对用户邮箱进行修改
sandy_address.email_address?=?"xiaoxiao@qq.com"


session.commit()

信息注释:

  • append就是追加的意思,查询到指定用户进行数据新增
  • email_address=是赋值操作,是查询到指定用户,对原有数据进行修改,也就是替换一个新的

#

一、数据删除

from?sqlalchemy.orm?import?Session
from?sqlalchemy?import?select


session?=?Session(engine)

stmt?=?select(User).where(User.name?==?"zhangsansan")
patrick?=?session.scalars(stmt).one()

stmt?=?select(User).where(User.name?==?"zhangsansan")
patrick?=?session.scalars(stmt).one()

stmt?=?(
????select(Address).join(
????????Address.user
????).where(
????????User.name?==?"lixiaoxiao"
????).where(
????????Address.user_id?==?2
????)
)
sandy_address?=?session.scalars(stmt).one()

#?一些删除
sandy?=?session.get(User,?2)
sandy.addresses.remove(sandy_address)
session.flush()

session.delete(patrick)
session.commit()

信息注释:

  • session.get(User, 2)是根据映射表获取数据
  • sandy.addresses.remove(sandy_address)根据查询到的数据进行删除
  • session.flush()是将所有对象更改刷新到数据库
  • session.delete(patrick)是根据查询到的进行删除

注意点:

  • remove一般来说,是操作对象还存在,只是从一个集合或容器中移除;而delete,则会执行销毁对象的操作,容器都不在了

今天先聊到这里吧,以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,直接私信留言会及时修正发布;非常期待你的一键 3 连【 点赞、收藏、分享 】哟,谢谢!

未完成,待续……

一直在努力,希望你也是!

微信搜索公众号:就用python

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:14:27  更:2022-05-05 11:18:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 9:28:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计