sqlalchemy从入门到熟悉(一)

news/2024/11/19 21:22:38/

sqlalchemy从入门到熟悉(一)

简介

SQLAlchemy SQL工具包和对象关系映射器是一套用于处理数据库和Python的综合工具。它有几个不同的功能领域,可以单独使用或组合使用。SQLAlchemy的两个最重要的面向前端的部分是对象关系映射器(ORM)以及Core。核心包含SQLAlchemy 的SQL以及数据库集成和描述服务的广度,其中最突出的部分是SQL表达式语言。

  1. SQL表达式语言是一个完全独立于ORM包的工具包,它提供了一个构造由可组合对象表示的SQL表达式的系统,然后可以针对特定事务范围内的目标数据库“执行”这些SQL表达式,并返回结果集。插入、更新和删除是通过传递表示这些语句的SQL表达式对象以及表示要与每个语句一起使用的参数的字典来实现的。

  2. ORM构建在Core之上,以提供使用映射到数据库模式的域对象模型的方法。在使用ORM时,SQL语句的构造方式与使用Core时基本相同,但是DML的任务是使用工作单元,它将针对可变对象的状态更改转换为INSERT、UPDATE和DELETE构造,然后根据这些对象调用这些构造。特定于ORM的自动化和以对象为中心的查询功能也增强了SELECT语句。

  3. 使用Core和SQL表达式语言提供了一个以模式为中心的数据库视图,以及一个面向不变性的编程范例,而ORM则在此基础上构建了一个以域为中心的数据库视图,具有更明显的面向对象和依赖于可变性的编程范例。由于关系数据库本身是可变服务,不同之处在于Core/SQL表达式语言是面向命令的,而ORM是面向状态的。

  4. 支持的安装方法

(1)使用PIP安装

pip install SQLAlchemy
# 安装最新的预缓解版本,使用--pre
pip install --pre SQLAlchemy

(2)SQLAlchemy安装是通过标准Python方法进行的,这些方法基于setuptools,可以通过引用setup.py直接使用。

python setup.py install

(3)检查已安装的SQLAlchemy版本

>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.4.41'

建立连接

  1. 任何SQLAlchemy应用程序的开始都是一个名为Engine。此对象充当连接到特定数据库的中心源,提供工厂和连接池。引擎通常是一个职位特定数据库服务器创建一次的全局对象,并使用一个URL字符串进行配置。
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:root@localhost:3306/test')

处理事务和DBAPI

  1. 获取连接
from sqlalchemy import create_engine, text
engine = create_engine('mysql+pymysql://root:root@localhost:3306/test')# with语句是python的上下文管理器
with engine.connect() as conn:result = conn.execute(text("select 'hello world'"))print(result.all())

结果:

[(‘hello world’,)]

  1. 提交更改
#DBAPI是非自动提交的,可以使用`commit()`方法提交
with engine.connect() as conn:conn.execute(text("create table demo(x int, y int)"))conn.execute(text("insert into demo(x, y) values(:x, :y)"), [{"x": 1, "y": 1}, {"x": 2, "y": 4}])conn.commit()
  1. 获取返回结果
with engine.connect() as conn:# REsul有很多用于获取和转换行的方法,类似于python的命名元组result = conn.execute(text("SELECT x, y FROM demo"))# 整数索引for row in result:print(f"x: {row.x}  y: {row.y}")# 元组赋值            for x, y in result:print(x)# 属性名称for row in result:y = row.y# 映射访问for dict_row in result.mappings():x = dict_row['x']               	        
  1. 将参数与语句绑定
# TextClause.bindparams()返回SQL构造的新副本,并添加了其他状态
stmt = text("select x, y from demo where y > :y order by x, y").bindparams(y=6)
  1. 使用ORM会话执行
from sqlalchemy.orm import Session
stmt = text("SELECT x, y FROM some_table WHERE y > :y ORDER BY x, y").bindparams(y=6)
with Session(engine) as session:result = session.execute(stmt)for row in result:print(f"x: {row.x}  y: {row.y}")

使用数据库元数据

  1. SQLAlchemy中数据库元数据最常见的基本对象是MetaDataTableColumn

  2. 使用表对象设置元数据

from sqlalchemy import MetaData
# MetaData对象是放置表的地方,一旦拥有了MetaData对象,可以声明一些Table物体
metadata_obj = MetaData()
from sqlalchemy import Table, Column, Integer, String
# Table表示数据库表并将其自身分配给MetaData收集
user = Table("user_account",metadata_obj,# Column表示数据库中的列,收藏Column对象的父对象Table通常位于Table.cColumn('id', Integer, primary_key=True),Column('name', String(30)),Column('fullname', String)
)user.c.name
user.c.keys()
  1. 使用ORM定义表元数据

(1)设置注册表

#使用ORM时,MetaData集合仍然存在,但是它本身包含`registry`中
from sqlalchemy.orm import registry
# registry在构造时,自动包含MetaData对象,该对象将存储Table
mapper_registry = registry()
mapper_registry.metadata
# 通过应用于映射类的指令间接声明Table对象
Base = mapper_registry.generate_base()
# 创建registry声明性基类可以使用declarative_base()功能
#from sqlalchemy.orm import declarative_base
#Base = declarative_base()

(2)声明映射类

# Base是一个python类,作为声明的OR吗映射类的基类
from sqlalchemy.orm import relationship
from sqlalchemy import Integer, String, ForeignKey, Columnclass User(Base):__tablename__ = 'user_account'id = Column(Integer, primary_key=True)name = Column(String(30))fullname = Column(String)addresses = relationship("Address", back_populates="user")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_account.id'))user = relationship("User", back_populates="addresses")def __repr__(self):return f"Address(id={self.id!r}, email_address={self.email_address!r})"

插入带核心的行

使用Core时,SQL INSERT语句是使用insert()函数表示SQL中的INSERT语句,将数据添加到表中。

(1)INSERT() SQL表达式构造

from sqlalchemy import insert
from sqlalchemy import create_engine
# stmt变量是Insert,大多数SQL表达式都可以串行化
stmt = insert(user_table).values(name='spongebob', fullname="Spongebob Squarepants")
print(stmt)
# 字符串形式是通过生活曾Compiled对象的形式
compiled = stmt.compile()
compiled.params
engine = create_engine('mysql+pymysql://root:root@localhost:3306/test')
with engine.connect() as conn:res = conn.execute(stmt)conn.commit()

(2)INSERT通常自动生成VALUES子句

with engine.connect() as conn:result = conn.execute(insert(user_table),[{"name": "sandy", "fullname": "Sandy Cheeks"},  {"name": "patrick", "fullname": "Patrick Star"}])conn.commit()

(3)插入从SELECT

select_stmt = select(user_table.c.id, user_table.c.name + "@aol.com")
insert_stmt = insert(address_table).from_select(["user_id", "email_address"], select_stmt)

(4)INSERT…RETURNING

insert_stmt = insert(address_table).returning(address_table.c.id, address_table.c.email_address)

使用核心或ORM选择行

select()函数会生成Select用于所有SELECT查询的构造,传递给这样的方法Connection.execute()Session.execute(),在当前事务中发出SELECT语句,结果行通过Result对象返回。

(1)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)

(2)设置COLUMNS和FROM子句

# 将所有字段名作为结果集返回
print(select(user_table))

(3)查询实例

from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base# 创建对象的基类,需要在数据库中创建表
Base = declarative_base()
class Person(Base):__tablename__ = 'person'id = Column(String(20), primary_key=True)name = Column(String(20))# 初始化数据库连接
engine = create_engine('mysql+pymysql://root:root@localhost:3306/test')
# 创建DBSession类型
DBSession = sessionmaker(bind=engine)
# 创建session对象
session = DBSession()
new_person = Person(id='5', name='Bob')
session.add(new_person)
session.commit()
person = session.query(Person).filter(Person.id=='5').one()
print('type:', type(person))
print('name:', person.name)
session.close()

http://www.ppmy.cn/news/98533.html

相关文章

Makefile基础教程(自动生成依赖关系)

文章目录 前言一、makefile不包含.h依赖的后果二、gcc -M 和 gcc -MM命令三、sed命令四、makefile中命令的执行机制四、生成依赖文件并单独放入文件夹中总结前言 在前面的文章中我们都只使用到了.c文件作为依赖但是在实际的工程中肯定是不可能只有.c文件的还存在.h文件,那么在…

一台服务器通过apache安装多个web应用

当我们只有一台linux服务器资源但有创建多个网站的需求时,我们可以通过安装一个网站服务器Apache进行搭建,此次服务器使用Centos 7 下面分别介绍一个域名多个端口和多个域名用Apache来搭建多个网站的操作过程。 一、使用apache 服务器 (一…

图的邻接矩阵表示

设图有n个顶点,则邻接矩阵是一个n*n的方阵;若2个顶点之间有边,则方阵对应位置的值为1,否则为0; 看几个例子; 此图的邻接矩阵是 0 1 1 1 1 0 1 0 1 1 0 1 1 0…

蓝桥杯嵌入式STM32G431RBT6竞赛指南与模板——最后的绝唱

谨以此文和我去年前的一篇蓝桥杯单片机的教程构成电子类的青铜双壁. 国信长天单片机竞赛训练之原理图讲解及常用外设原理(遗失的章节-零)_昊月光华的博客-CSDN博客 目录 时钟树 串口重定向:printf输出 动态点灯(点灯大师) 按键(常用状态…

Python代码写好了怎么运行

Python代码写好了怎么运行?相信问这样问题的朋友一定是刚刚入门Python的初学者。本文就来为大家详细讲讲如何运行Python代码。 一般来讲,运行Python代码的方式有两种,一是在Python交互式命令行下运行;另一种是使用文本编辑器&…

logstash 采集的文件mv后

1.logstash [oswatch@rce1 conf]$ cat test.conf input { file { path=>["/tmp/test/test.log*"] } } output { stdout { codec=>rubydebug{} } } 2.python脚本: [oswatch@rce1 conf]$ cat t1.py #!/usr/bin/python # -*- coding: UTF-…

virtualbox报错

virtualbox 报错 See “systemctl status virtualbox.service” and “journalctl -xe” for details. invoke-rc.d: initscript virtualbox, action “restart” failed. ● virtualbox.service - LSB: VirtualBox Linux kernel module Loaded: loaded (/etc/init.d/virtualbo…

Mysql面试必知的知识点-干货分享

文章目录 底层索引为什么使用B树,而不用B树?为什么Innodb索引建议必须建主键?为什么主键推荐使用整形自增?Mysql底层索引只有B树吗?联合索引底层长什么样子?数据库隔离级别中串行化是怎么实现的?查询方法需要加事务吗?大事务有什么影响? 底层索引为什么使用B树,而不用B…