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

在这里插入图片描述

四、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.mzph.cn/news/625851.shtml

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

相关文章

Python简单ORM实现:不使用元类的灵活数据操作与查询构建【第29篇—python:ORM】

文章目录 不使用元类的简单ORM实现Field类Compare类Model类Query类示例使用扩展查询功能支持 LIMIT 和 OFFSET支持 GROUP BY 和 HAVING 示例用法总结 不使用元类的简单ORM实现 在 Python 中,ORM(Object-Relational Mapping)是一种将对象和数…

GBASE南大通用CommandBuilder 属性

DataAdapter 属性 获取或设置一个用于自动生成 SQL 语句的GBASE南大通用DataAdapter 对象。  语法 [Visual Basic] Public Property DataAdapter As GBASE南大通用DataAdapter Get Set [C#] public GBaseDataAdapter DataAdapter { get; set; }  属性 一个 GBase…

244.【2023年华为OD机试真题(C卷)】密码解密(JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目二.解题思路三.题解代码Python题解代码JAVA题解…

基于uniapp的在线课程教学系统

介绍 项目背景: 随着互联网的快速发展,在线教育已经成为一种流行的学习方式。针对这一趋势,我们决定开发一个基于UniApp的在线课程教学系统。该系统旨在为学生提供方便快捷的在线学习体验,同时也为教师提供一个高效管理课程的平台…

Vue3实现带点击外部关闭对应弹出框(可共用一个变量)

首先,假设您在单文件组件(SFC)中使用了Vue3,并且有两个div元素分别通过v-if和v-else来切换显示一个带有.elpopver类的弹出组件。在这种情况下,每个弹出组件应当拥有独立的状态管理(例如:各自的isOpen变量)。…

QFile:文件的打开与关闭

QFile file("注释.txt");if(file.open(QIODevice::WriteOnly)){qDebug()<<"打开成功";}else{qDebug()<<"打开失败";}if(file.open(QIODevice::WriteOnly)){qDebug()<<"打开成功";}else{qDebug()<<"打开失…

《计算机视觉处理设计开发工程师》

计算机视觉&#xff08;Computer Vision&#xff09;是一门研究如何让计算机能够理解和分析数字图像或视频的学科。简单来说&#xff0c;计算机视觉的目标是让计算机能够像人类一样对视觉信息进行处理和理解。为实现这个目标&#xff0c;计算机视觉结合了图像处理、机器学习、模…

做品牌,怎么挖掘用户深层需求?

品牌想要长久发展&#xff0c;就需要去挖掘用户深层需求&#xff0c;什么是用户深层需求&#xff0c;比如做美业的认为用户想要变美是深层次的需求&#xff0c;但其实由美貌带来的附加利益比如说更上镜、竞争优势更大等才属于深层需求&#xff0c;今天媒介盒子就来和大家聊聊&a…

compose 实验

cd /opt mkdir compose_nginx cd compose_nginx mkdir nginx cd nginx/ 此时顺便将nginx安装包拖进来 vim Dockerfile mkdir /opt/compose_nginx/wwwroot echo "<h1>this is test web</h1>" > /opt/compose_nginx/wwwroot/index.html docker netw…

HashTable, HashMap, ConcurrentHashMap 之间的区别

1. 线程安全性 HashTable&#xff1a;HashTable是线程安全的&#xff0c;所有操作都是同步的&#xff08;synchronized关键字&#xff09;。这意味着多个线程可以同时访问HashTable&#xff0c;并且不会导致数据不一致的问题。然而&#xff0c;由于同步的开销比较大&#xff0…

【C语言知识】原码反码和补码

一&#xff0c;简介 总结进制转换&#xff0c;原码&#xff0c;反码和补码相关基础知识。 二&#xff0c;具体说明 2.1 十进制转二进制方法 14(D)转换为二进制为&#xff08;0000 1110 &#xff09; -21(D)转换为二进制为&#xff08;1001 0101&#xff09;&#xff0c;先…

二分查找与搜索树的高频问题(算法村第九关白银挑战)

基于二分查找的拓展问题 山峰数组的封顶索引 852. 山脉数组的峰顶索引 - 力扣&#xff08;LeetCode&#xff09; 给你由整数组成的山脉数组 arr &#xff0c;返回满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i 1] > ... > arr[arr.length - 1…

git 提炼笔记

1、设置用户名和邮箱&#xff08;邮箱可以不是真的&#xff09; git config --global user.name test101 // 设置用户名为 test101git config --global user.email test101test101.cn // 设置邮箱为test101test101.cn2、查看用户名和邮箱 git config --global user.name git…

索引的数据结构(MySql高级)

索引的数据结构 为什么使用索引什么是索引索引的优缺点优点缺点 常见索引概念聚簇索引二级索引(辅助索引, 非聚簇索引)InnoDB的B树索引的注意事项 MyISAM 与 InnoDB 对比索引的代价 为什么使用索引 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教…

用使用pandas拆分excel单元格

要使用pandas拆分Excel单元格&#xff0c;你可以使用pandas的read_excel函数读取Excel文件&#xff0c;然后使用str.split()方法拆分单元格。 以下是一个示例代码&#xff0c;演示如何使用pandas拆分Excel单元格&#xff1a; python复制代码 import pandas as pd # 读取Excel…

基于SSM的网上购物商城设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

代理IP安全使用指南:隐私保护与风险规避措施

代理IP安全使用指南&#xff1a;隐私保护与风险规避措施 一、选择可信的代理IP服务 - 付费代理优于免费代理&#xff1a;为了确保数据安全和隐私保护&#xff0c;优先考虑使用信誉良好、有偿的代理IP服务。这些服务通常会提供更好的匿名性&#xff0c;更少的数据记录&#xf…

Vue知识总结-下

VUE-组件间通信 组件的自定义事件 概述&#xff1a;是一种组件间通信的方式,适用于&#xff1a;子组件>父组件使用场景&#xff1a;A是父组件,B是子组件,B给A传递数据,那么需要在A组件中绑定自定义事件(事件的回调也在A中)使用步骤 绑定自定义事件&#xff1a; 第一种方式…

windows系统Typora快捷键

文章目录 File&#xff08;文件&#xff09;Edit&#xff08;编辑&#xff09;Paragraph&#xff08;段落&#xff09;Format&#xff08;格式&#xff09;View&#xff08;界面&#xff09; 较实用的快捷键总结如下 File&#xff08;文件&#xff09; 功能快捷键创建新文件Ct…

Python展示 RGB立方体的二维切面视图

代码实现 import numpy as np import matplotlib.pyplot as plt# 生成 24-bit 全彩 RGB 立方体 def generate_rgb_cube():# 初始化一个 256x256x256 的三维数组rgb_cube np.zeros((256, 256, 256, 3), dtypenp.uint8)# 填充立方体for r in range(256):for g in range(256):fo…