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

news2024/9/24 19:24:28

在这里插入图片描述

四、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 对象

drop_all() 删除所有表

reflect() 从database已存在表创建table
使用方法:
读取db所有表,

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’]

读取指定表

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

如果存在外键, load主表时,也会自动加载辅表,
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.coloradmin.cn/o/1387936.html

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

相关文章

前端框架前置学习Node.js(2)npm使用,Node.js总结

npm - 软件包管理器 定义 npm是Node.js标准的软件包管理器 npm仓库中包含大量软件包,使其成为世界上最大的单一语言代码仓,并且可以确定几乎可用于一切的软件包 最初是为了下载和管理Node.js包依赖的方式,但其现在已成为前端JavaScript中使用的工具 使用: 1.初始化清单文…

VC++读取ini文件示例2

之前学习过ini文件读写;继续熟悉; CString str1;UINT m1 0;UINT m2 0;TCHAR p1[32];m1 GetPrivateProfileString(_T("mymoney1"), _T("moneyname1"), _T("空"), p1, sizeof(p1), _T("E:\\VCPrj\\VC2015\\cattest\…

免费的域名要不要?

前言 eu.org的免费域名相比于其他免费域名注册服务,eu.org的域名后缀更加独特。同时,eu.org的域名注册也比较简单,只需要填写一些基本信息,就可以获得自己的免费域名。 博客地址 免费的域名要不要?-雪饼前言 eu.org…

FPGA之LUT

由于FPGA需要被反复烧写,它实现组合逻辑的基本结构不可能像ASIC那样通过固定的与非门来完成,而只能采用一种易于反复配置的结构。查找表可以很好地满足这一要求,目前主流FPGA都采用了基于SRAM工艺的查找表结构。LUT本质上就是一个RAM.它把数据事先写入RAM后,每当输入一个信号就…

【QML COOK】- 009-组件(Components)

组件对于QML来说就如同C的类一样。可以用同一个组件创建多个对象。 组件有两种定义方式: 用独立的.qml文件定义组件在.qml文件中用Component对象定义组件 1. 创建项目,新建文件IndependentComponent.qml import QtQuickRectangle {id : rootText {id…

2.3 数据链路层03

2.3 数据链路层03 2.3.7 以太网交换机 1、以太网交换机的基本功能 以太网交换机是基于以太网传输数据的交换机,以太网交换机通常都有多个接口,每个接口都可以直接与一台主机或另一个以太网交换机相连,一般都工作在全双工方式。 以太网交换…

go中如何进行单元测试案例

一. 基础介绍 1. 创建测试文件 测试文件通常与要测试的代码文件位于同一个包中。测试文件的名称应该以 _test.go 结尾。例如,如果你要测试的文件是 math.go,那么测试文件可以命名为 math_test.go。 2. 编写测试函数 测试函数必须导入 testing 包。每…

一文读懂「Large Language Model,LLM」大语言模型

中国大语言模型产业价值链 资料 艾瑞咨询:https://www.iresearch.com.cn/Detail/report?id4166&isfree0&type

《C++大学教程》4.34阶乘

题目: 对一个非负整数n来说,它的阶乘可以写成 n! (读作“n的阶乘”),其计算公式定义如下: n! n x (n-1) x (n-2)x......x1(对于大于1的 n ) 和 n! 1 ( 对于等于0或者等于1的n ) 例如,5&…

深信服技术认证“SCSA-S”划重点:逻辑漏洞

为帮助大家更加系统化地学习网络安全知识,以及更高效地通过深信服安全服务认证工程师考核,深信服特别推出“SCSA-S认证备考秘笈”共十期内容,“考试重点”内容框架,帮助大家快速get重点知识~ 划重点来啦 *点击图片放大展示 深信服…

助力工业焊缝质量检测,YOLOv7【tiny/l/x】不同系列参数模型开发构建工业焊接场景下钢材管道焊缝质量检测识别分析系统

焊接是一个不陌生但是对于开发来说相对小众的场景,在我们前面的博文开发实践中也有一些相关的实践,感兴趣的话可以自行移步阅读即可:《轻量级模型YOLOv5-Lite基于自己的数据集【焊接质量检测】从零构建模型超详细教程》 《基于DeepLabV3Plus…

视频剪辑批量工作流程:视频色调调整让影片更出色,视频制作的方法

随着视频制作需求的不断增加,高效的批量工作流程在视频剪辑中变得越来越常见。色调调整是提升影片质量的部分环节。现在一起来看云炫AI智剪如何批量调整视频色调的操作。 原视频与色调调整后的视频效果对比。 视频色调调整的详细步骤: 操作1、在云炫AI…

【Python】tensor格式数据转为图像,并保存图像详解和示例

在项目中遇到一个tensor格式的数据,要保存为图像,此文对转换过程通过示例分享,以记录学习过程和帮助大家遇到同类问题时使用。 import torch import cv2 import numpy as np# 创建一个示例张量(tensor) input_tensor …

使用 TiUP 部署 TiDB 集群

TIDB优点 支持分布式且支持事务的关系型数据库,不用考虑分库分表 同时满足了可伸缩,高可用,关系型,支持事务。 基本上按官网的文档来就行了。 在线部署 以普通用户身份登录中控机。以 tidb 用户为例,后续安装 TiUP …

每日一练:LeeCode-144、145、94.二叉树的前中后序遍历【二叉树】

本文是力扣LeeCode-144、145、94.二叉树的前中后序遍历 学习与理解过程,本文仅做学习之用,对本题感兴趣的小伙伴可以出门左拐LeeCode前序遍历、中序遍历、后序遍历。 给你二叉树的根节点 root ,返回它节点值的 前序遍历。 给定一个二叉树的根…

Mendeley Word 文献引用

这里写目录标题 1. 下载Mendeley 并插入到Word1.1 下载安装1.2 在Word 中添加Mendeley 插件文献引用相关 1. 下载Mendeley 并插入到Word 1.1 下载安装 Mendeley 官网下载 1.2 在Word 中添加Mendeley 插件 打开 Mendeley,点击 Tools —>Install Mendeley Cite…

Qt6入门教程 6:Qt元对象系统

目录 一.什么是Qt元对象系统? 二.编译时Qt Creator偷摸做了哪些事情? 1.uic 2.rcc 3.moc 一.什么是Qt元对象系统? Qt中的元对象系统(Meta-Object System)提供了对象间通信的信号和槽机制、运行时类型信息和动态属…

电池包的UL9540A,电池PACK的UL9540A,工商储的UL9540A,电芯的UL9540A,电池模组的UL9540A,家储的UL9540A

电池包的UL9540A,电池PACK的UL9540A,工商储的UL9540A,电芯的UL9540A,电池模组的UL9540A,家储的UL9540A UL9540A要求ESS在不同条件下进行测试,并要求满足特定的性能要求。测试包括热暴露测试、短路测试、过充电和过放电测试、外部影响测试等。…

从零开发短视频电商 PaddleOCR Java推理 (四)优化OCR工具类

从零开发短视频电商 PaddleOCR Java推理 (四)优化OCR工具类 参考:https://github.com/mymagicpower/AIAS/blob/9dc3c65d07568087ac71453de9070a416eb4e1d0/1_image_sdks/ocr_v4_sdk/src/main/java/top/aias/ocr/OcrV4RecExample.java import …

统计学之常见的分布介绍

统计学中常见的分布有: 1. 正态分布(Normal Distribution):也称为高斯分布,是最常见的分布之一,具有钟形曲线,对称且均值和标准差可以完全描述该分布。 2. 二项分布(Binomial Dist…