SqlAlchemy使用教程(四) MetaData 与 SQL Express Language 的使用

在这里插入图片描述

  • SqlAlchemy使用教程(一) 原理与环境搭建
  • SqlAlchemy使用教程(二) 入门示例及编程步骤
  • SqlAlchemy使用教程(三) CoreAPI访问与操作数据库详解
  • SqlAlchemy使用教程(四) MetaData 与 SQL Express Language 的使用
  • SqlAlchemy使用教程(五) ORM API 编程入门

四、Database MetaData 与 SQL Express Language 的使用

MetaData对象用于描述表结构,SQL Express Language是DBAPI SQL的统一封装器。MetaData 与SQL Express 语句可以在Core层使用,ORM层基于MetaData, SQL Express基础上做了进一步抽象。本章将介绍在Core层如何使用MetaData与SQL Express Language语句。

1、使用MetaData定义表结构

MetaData的含义

  • MetaData 相当于python层的db schema,即数据库结构定义, 用meta.Table对象来表示table 定义,Column对象来表示 column的定义,
  • 通常1个模块只包含1个metaData对象,可以包含多个table定义。

Step-1, 创建1个MetaData对象

from sqlalchemy import MetaData
metadata_obj = MetaData()

Step-2 申明 Table对象

创建了MetaData对象后,就可以用它来声明Table对象,每个字段用Column对象来表示

user_table = Table('user_account',metadata_obj,Column('id',Integer,primary_key=True),Column('name',String(30)),Column('speciality',String(30)),
)

说明:

  • user_acount是数据库的table名。
  • user_table 则是meta.Table的实例对象,后面的操作,使用此对象名

必须说明,本例用 metadata 定义表结构的方式,不是ORM 表结构定义方式。

Step-3 Columns 对象

MetaData对象column对象来表示数据库字段,其主要属性

  • name, type object,
  • autoincrement
  • default
  • index
  • info
  • nullable
  • unique
  • primary_key
  • comment
  • insert_sentinel ( 插入执行结果检查)

table对象的 c属性 , 即 table.c
所有列名被放进 table.c数组中,引用列名方式:user_table.c.name

column数据类型
Alchemy 提供了足够的column数据类型,注意类型命名采用CamelCase风格,主要有:
Boolean Integer SmallInteger BigInteger Float Double String
Text Time Date DateTime Enum LargeBinary PickleType等。

Step-4: 定义Primary key、index, foreign key

Primary Key

Column("id", Integer, primary_key=True),

Index

Column(‘Addres’, String, index=True) 

Foreign key

Column("user_id", ForeignKey("user_account.id"), nullable=False),

Step-5: 发送 DDL 指定到数据库创建表

DDL 即create 语句,用MetaData对象的 create_all(),可将该对象上的所有 Table对象转为DDL发送给数据库

metadata_obj.create_all()

此方法会先查询DB中是否存在该表,再进行创建。

MetaData的其它方法

MetaData.tables 返回保存的所有 table 对象列表,

print(meta_obj.tables) 
user_account_tbl = meta_obj.tables['user_account']

删除所有表

meta_obj.drop_all()   

根据已存在数据库反向生成 metadata Table对象

此功能通过 metadata类的reflect() 方法实现。

(1) 读取数据库中所有表结构.
生成的 table 对象保存在 metadata.tables 中。

engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/test_db?charset=utf8")
meta_obj = MetaData() 
meta_obj.reflect(bind=engine) 
school_table = meta_obj.tables[‘school’]

(2) 读取指定表,生成单个table对象

>>> messages = Table("messages", metadata_obj, autoload_with=engine)
>>> [c.name for c in messages.columns]
['message_id', 'message_name', 'date']

(3) 读取有外键字段的表
如果读取数据库表时,如果该表存在外键字段, 加载时,会自动加载关联表
shopping_cart_items 外键字段引用了shopping_cards, 也被加载了

>>> shopping_cart_items = Table("shopping_cart_items", metadata_obj, autoload_with=engine)
>>> "shopping_carts" in metadata_obj.tables
True

2、SQL Express Language 使用

2.1 NSERT() 方法

Insert 单条数据 :

with engine.connect() as conn: stmt = insert(asset_table).values(name="打印机",tag="A0001",value=3000,user_id=1)result = conn.execute(stmt)conn.commit()print(result.inserted_primary_key)

判断插入结果 result 是否成功,
通过检查 result.inserted_primary_key, 如果为None表示插入失败。

插入多条数据

with engine.connect() as conn:     # send many statements rows = [{'name':'复印机','tag': 'A0002', 'value': 29000, 'user_id': 4 },{'name':'20吨吊车','tag': 'D0001', 'value': 240000, 'user_id': 1 },]conn.execute( asset_table.insert(), rows )conn.commit()

2.2 Select()方法

基本使用方法

from sqlalchemy import select
stmt = select(user_table).where(user_table.c.name == "spongebob")
print(stmt)
with Session(engine) as session:for row in session.execute(stmt):print(row)

选择部分字段:

select(user_table.c.name, user_table.c.fullname))

修改列名,

from sqlalchemy import func, cast
stmt = select(("Username: " + user_table.c.name).label("username"),).order_by(user_table.c.name)
with engine.connect() as conn:for row in conn.execute(stmt):print(f"{row.username}")

output

Username: 张锋
Username: 海绵宝宝
Username: 王小乙

Where 子句

select(user_table).where(user_table.c.name == "squidward"))
>>> print(
...     select(address_table.c.email_address)
...     .where(user_table.c.name == "squidward")
...     .where(address_table.c.user_id == user_table.c.id)
... )

相当于SQL

SELECT address.email_address
FROM address, user_account
WHERE user_account.name = :name_1 AND address.user_id = user_account.id

join 联合查询

>>> print(
...     select(address_table.c.email_address)
...     .select_from(user_table)
...     .join(address_table, user_table.c.id == address_table.c.user_id)
... )
SELECT address.email_address
FROM user_account JOIN address ON user_account.id = address.user_id

2.3 数据更新update()与删除 Delete()

1) 更新数据

方法: Update()

stmt = update(user_table).values(fullname="Username: " + user_table.c.name)

更新多条数据 示例 :

>>> from sqlalchemy import bindparam
>>> stmt = (
...     update(user_table)
...     .where(user_table.c.name == bindparam("oldname"))
...     .values(name=bindparam("newname"))
... )
>>> with engine.begin() as conn:
...     conn.execute(
...         stmt,
...         [
...             {"oldname": "jack", "newname": "ed"},
...             {"oldname": "wendy", "newname": "mary"},
...             {"oldname": "jim", "newname": "jake"},
...         ],
...     )

有外键数据更新

>>> scalar_subq = (
...     select(address_table.c.email_address)
...     .where(address_table.c.user_id == user_table.c.id)
...     .order_by(address_table.c.id)
...     .limit(1)
...     .scalar_subquery()
... )
>>> update_stmt = update(user_table).values(fullname=scalar_subq)
>>> print(update_stmt)
2) 删除数据

主法: delete()

示例:

from sqlalchemy import delete
stmt = (delete(user_table).where(user_table.c.id == 5)
)
result = conn.execute(stmt) 

Delete操作返回值类型为 CursorResult,可以用 result.rowcount 查看受影响行数,以确定是否成功。

多表删除:

delete_stmt = (delete(user_table).where(user_table.c.id == address_table.c.user_id).where(address_table.c.email_address == "patrick@aol.com")
)
from sqlalchemy.dialects import mysql
print(delete_stmt.compile(dialect=mysql.dialect()))DELETE FROM user_account USING user_account, address
WHERE user_account.id = address.user_id AND address.email_address = %s

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

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

相关文章

WebRTC视频会议/视频客服系统EasyRTC进入会议室密码验证的开发与实现

基于WebRTC技术的EasyRTC视频会议系统,建设目标是让用户随时随地、快捷方便地进行视频会议,并根据行业需求有针对性地提供多样化、个性化功能,该系统是覆盖全球的实时音视频开发平台,支持一对一、一对多等视频通话,极大…

上门服务系统|上门服务小程序|上门服务系统的发展趋势

在现代社会,人们的生活节奏越来越快,对于更加便捷的服务需求也随之增加。正是基于这一背景,上门服务系统应运而生,并且迅速发展壮大。那么,上门服务系统的发展趋势又是怎样的呢? 首先,上门服务系…

Spring MVC学习之——自定义日期转化器

日期转换器 在数据库中的日期数据是date类型,而如何我们想在页面自己添加数据,一般是使用年-月-日的形式,这种形式不仅date类型接收不到,而且传来的是String类型,此时,我们就可以自定义日期转换器来接收数…

k8s的坑,从这里开始

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 以前刚接触k8s时踩了不少坑,比如这些: 问题1 1、在master节点使用kubectl命令时,报错&…

如何打造企业内部流程系统?

企业的发展过程中,要不断收集员工的建议,以改进自身的流程并增强自身的竞争力。 除此之外,企业也希望员工能积极为公司提出更多的创意和提案,共同加强企业的建设。 那么针对这类场景,我们应该如何在企业内部推动呢&a…

任意文件读取漏洞

一.任意文件读取概述 ​ 一些网站的需求,可能会提供文件查看与下载的功能。如果对用户查看或下载的文件没有限制或者限制绕过,就可以查看或下载任意文件这些文件可以是源代码文件,配置文件,敏感文件等等。 任意文件读取会造成&am…

redis数据安全(三)数据持久化 AOF

接上一篇RDB,本篇看下Redis数据持久化的第二种方式AOF。 目录 一、AOF原理 1、写入机制: 2、缓冲机制: 3、重写机制 : 4、运行流程 二、AOF文件配置 1、开启AOF: 2、自动触发AOF重写 3、重写规则&#xff1…

Unity Mirror VR联机开发 实战篇(二)

一、迁移示例中的联机物体 1、将MirrorExamplesVR工程中的部分文件夹复制到自己的工程中。 1、打开MirrorExamplesVR中的 SceneVR-Common场景。 2、将场景中没用的东西都删掉,只留下面这些,新建一个空物体XR Mirror,将所有剩下的物体拖成XR …

Spring Boot自动配置原理

1.SpringBootApplication注解 springboot是基于spring的新型的轻量级框架,最厉害的地方当属**自动配置。**那我们就可以根据启动流程和相关原理来看看,如何实现传奇的自动配置 SpringBootApplication//标注在某个类上,表示这个类是SpringBo…

Redis内部数据结构skiplist详解

我们将大体分成三个部分进行介绍: 介绍经典的skiplist数据结构,并进行简单的算法分析。这一部分的介绍,与Redis没有直接关系。我会尝试尽量使用通俗易懂的语言进行描述。 讨论Redis里的skiplist的具体实现。为了支持sorted set本身的一些要求…

15.云原生之k8s容灾与恢复实战

云原生专栏大纲 文章目录 Velero与etcd介绍Velero与etcd备份应用场景Velero与etcd在k8s备份上的区别 Velero备份恢复流程备份工作流程Velero备份时,若k8s集群发送变化,会发发生情况?Velero 备份pv,pv中数据变化,会发发…

酷炫的公司年会抽奖(附源码)

源码:年会抽奖: 年会会议抽奖项目,支持照片上传 (gitee.com) 效果展示 年会抽奖演示 主界面 功能简介 支持excel复制导入成员名单 自定义奖项及人数 抽奖方式灵活 1. 可以一次一个 也可一次全部抽取完毕 2. 可选择已中奖人后续是否还可继续参与抽奖…

2024美赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

Mybatis中#{}与${}的区别

sql注入 Sql注入指的是程序解析时会将你传入的参数作为原来SQL语句的一部分,打乱原来SQL的结构,而通常我们只是需要传入一个参数而已. 防止SQL注入,首先要对密码输入中的单引号进行过滤,再在后面加其它的逻辑判断,或者…

mac PyCharm 使用conda环境

1 使用conda创建虚拟环境 conda create -n test6 python3.9 -y conda activate test62 选择conda环境 本地 选择已经存在的conda环境 右下角会显示现在的环境。

用git bash调用md5sum进行批量MD5计算

对于非常大的文件或者很重要的文件,在不稳定的网络环境下,可能文件的某些字节会损坏。此时,对文件计算MD5即可以校验其完整性。比如本次的 OpenStreetMap 导出包,我的学弟反馈通过网盘下载无法解压,并建议我增加每个文…

Hardware-Aware-Transformers开源项目笔记

文章目录 Hardware-Aware-Transformers开源项目笔记开源项目背景知识nas进化算法进化算法代码示例 开源项目Evolutionary Search1 生成延迟的数据集2 训练延迟预测器3 使延时约束运行搜索算法4. 训练搜索得到的subTransformer5. 根据重训练后的submodel 得到BLEU精度值 代码结构…

基于arcgis js api 4.x开发点聚合效果

一、代码 <html> <head><meta charset"utf-8" /><meta name"viewport"content"initial-scale1,maximum-scale1,user-scalableno" /><title>Build a custom layer view using deck.gl | Sample | ArcGIS API fo…

从争议到巅峰:Vue3 的奇迹之旅 —— 从‘海贼王’到‘灌篮高手’的变革历程

前端训练营&#xff1a;1v1私教&#xff0c;终身辅导计划&#xff0c;帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~ Hello&#xff0c;大家好&#xff0c;我是 Sunday。 Vue 官方团队在 2023 年的最后两天发布了 Vue 3.4 的版本命名为 “Sla…

JAVA——数据类型与运算符

数据类型 注意事项&#xff1a;1.初始化操作是可选的, 但是建议创建变量的时候都显式初始化. 2.最后不要忘记分号, 否则会编译失败. 3.初始化设定的值为 10L , 表示一个长整型的数字. 10l 也可以. 4.float 类型在 Java 中占四个字节, 遵守 IEEE 754 标准. 由于表示的数据精度范…