Sqlalchemy学习

server/2024/11/29 23:00:45/

连接数据库

import sqlalchemydatabase_url = 'mysql+pymysql://username:password@localhost:3306/database'
# pymysql 需要下载包 pip install pymysql
engine = sqlalchemy.create_engine(database_url)  # 创建了一个数据库引擎# 测试连接
try:with engine.connect() as connection:print("数据库连接成功")
except Exception as e:print(f"连接失败: {e}")

单表操作

import sqlalchemy
from sqlalchemy.orm import sessionmaker
# declarative_base 是 SQLAlchemy 的基类,用于定义数据模型
from sqlalchemy.orm import declarative_basefrom sqlalchemy import Column, Integer, Stringdatabase_url = 'mysql+pymysql://username:password@localhost:3306/database'
engine = sqlalchemy.create_engine(database_url)  # 创建了一个数据库引擎
# 测试连接
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) # 创建了一个会话类,用于与数据库交互
Base = declarative_base()class User(Base):__tablename__ = "users"# __tablename__ 指定了表名# Column 定义了表中的列及其类型id = Column(Integer, primary_key=True, index=True)# id,Integer 类型,primary_key为主键name = Column(String(255), index=True)# String 字符类型,255最大长度,类似于django ORM的 CharField,max_length=255# index=True 表示为该列创建索引,以便在按 name 列进行查询时提高性能# unique 唯一值,唯一索引email = Column(String(255), unique=True, index=True)# Base.metadata.create_all(bind=engine) 这句话表示创建所有的表
Base.metadata.create_all(bind=engine)

当我们运行这个py文件,他就会执行create_all 这个函数,那么就会把我们的user这张表创建在库中

新增数据

from main import SessionLocal
from moudel import Userdb = SessionLocal()
# 创建一个新的 User 对象,并初始化 name 和 email 属性
new_user = User(name='zh', email='152@163.com')
# 将新创建的 User 对象添加到当前的数据库会话中。这意味着在提交事务时,这个对象将被插入到数据库中
db.add(new_user)
# 提交当前的数据库会话,将所有在会话中进行的更改(包括插入新用户)持久化到数据库中
db.commit()
# 刷新 new_user 对象,使其包含最新的数据库状态。这通常用于确保对象的属性(如自动生成的 id)是最新的
db.refresh(new_user)

查询数据

查询单个
usr_a = db.query(User).filter(User.email == '').first()
print(usr_a.id)
print(usr_a.name)
print(usr_a.email)
查询所有
user_all = db.query(User).all()
print(user_all, type(user_all))  # 类型是 <class 'list'> ,可以for循环拿
for user in user_all:print(user.id)

修改数据

usr_a = db.query(User).filter(User.email == '').first()
usr_a.name = '彭于晏'
# 这个commit 可以理解为django的save()方法,只是django中有模型类对象.save(),sqlalchemy中用的会话
# 对象
db.commit()
print(usr_a.name)  # 彭于晏

删除数据

usr_a = db.query(User).filter(User.email == '').first()
db.delete(usr_a)
db.commit()

and与or查询

可以直接在 filter 方法中使用多个条件,用逗号分隔,这相当于使用 and 逻辑

usr_a = db.query(User).filter(User.email == '', User.name == '').first()
print(usr_a.id)

我们导入_or 来进行查询

from sqlalchemy import or_usr_a = db.query(User).filter(or_(User.name == '', User.name == '')).all()
print(usr_a, type(usr_a))  # 这个类型还是list,结果几个都是放在列表中

关于查询我们需要知道,如果我们没有执行.all()或者.first(),那么只会创建一个查询对象,也就是我们的SQL语句,点.all()或者.first()才会真正的执行查询语句

usr_a = db.query(User).filter(or_(User.name == '', User.name == '')) 返回的是一个 Query 对象,而不是实际的查询结果。Query 对象代表了一个待执行的查询,直到你调用 all()first()one() 等方法才会实际执行查询并返回结果

 多表操作

一对一表创建

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationshipclass UserInfo(Base):__tablename__ = "user_info"id = Column(Integer, primary_key=True)address = Column(String(255), index=True)user = relationship("User", back_populates="userinfo")
# relationship("User", back_populates="userinfo",uselist=False):定义了一个关系属性 user,表示 UserInfo 和 User 之间的一对一关系
# back_populates="userinfo":指定反向引用的属性名称,即在 User 模型中定义的 userinfo 属性
# uselist=False:表示这是一个一对一关系,而不是一对多关系。默认情况下,relationship 会创建一个列表,uselist=False 使它返回单个对象class User(Base):__tablename__ = "users"id = Column(Integer, primary_key=True, index=True)name = Column(String(255), index=True)email = Column(String(255), unique=True, index=True)userinfo_id = Column(Integer, ForeignKey('user_info.id'), unique=True)userinfo = relationship("UserInfo", back_populates="user")
# Column(Integer, ForeignKey('user_info.id'), unique=True):定义了一个整数类型的列 #userinfo_id,并将其设置为外键(foreign key),引用 user_info 表的 id 列。同时,unique=True 确保# 每个 User 对象只能有一个 UserInfo 对象
# userinfo:relationship("UserInfo", back_populates="user"):定义了一个关系属性 userinfo,
# 表示 User 和 UserInfo 之间的一对一关系。
# "UserInfo":指定关系的目标模型。
# back_populates="user":指定反向引用的属性名称,即在 UserInfo 模型中定义的 user 属性

relationship:用于定义关系

userinfo_id:是一个外键,指向 UseInfo表的 id 字段

userinfo:是一个关系属性,类型为 UserInfo,并通过 back_populates 参数指定了反向引用的属性名称为 user

一对一创建数据

# 一对一创建数据,先创建没有外键字段的表
user_info = UserInfo(address='上海')
user = User(name='', email='', userinfo=user_info)
db.add(user)
db.commit()
db.refresh(user)

一对一跨表查询

使用 join 进行跨表查询

# 查询所有用户的姓名和地址
results = db.query(User.name, UserInfo.address).join(UserInfo).all()
for result in results:print(f"Name: {result.name}, Address: {result.address}")# 按照用户名查询单个用户信息
result = db.query(User.name, UserInfo.address).join(UserInfo).filter(User.name == '').first()
print(result, type(result))  # 类型:<class 'sqlalchemy.engine.row.Row'>

 使用 subquery 进行跨表查询

from sqlalchemy.orm import aliased
from sqlalchemy.sql import select# 创建别名
userinfo_alias = aliased(UserInfo)# 创建子查询
subquery = db.query(userinfo_alias.id, userinfo_alias.address).subquery()# 使用子查询进行查询
results = db.query(User.name, subquery.c.address).join(subquery, User.userinfo_id == subquery.c.id).all()for result in results:print(f"Name: {result.name}, Address: {result.address}")

使用 outerjoin 进行左连接查询

如果你需要进行左连接查询(即即使某些用户没有对应的 UserInfo 也能查询到),可以使用 outerjoin

# 查询所有用户的姓名和地址,即使某些用户没有对应的 UserInfo
results = db.query(User.name, UserInfo.address).outerjoin(UserInfo).all()for result in results:print(f"Name: {result.name}, Address: {result.address or 'N/A'}")

删除的话肯定要先删除有外键的,然后再删除没有外键的


http://www.ppmy.cn/server/146014.html

相关文章

【君正T31开发记录】8.了解rtsp协议及设计模式

前边搞定了驱动&#xff0c;先不着急直接上手撸应用层的代码&#xff0c;先了解一下大致要用到的东西。 设计PC端先用vlc rtsp暂时H264编码&#xff08;vlc好像不支持h265,这个后边我试试&#xff09;的视频流&#xff0c;先需要支持上rtsp server&#xff0c;了解rtsp协议是必…

C#-winform:项目打包

一、安装扩展包 1、打开扩展界面&#xff0c;增加可以打包为exe文件的工具 扩展->管理扩展 2、搜索并下载扩展 Microsoft Visual Studio Install Projects 注&#xff1a;安装的时候会推出visual studio的&#xff0c;重启一下就会生效&#xff0c;搜到Setup Project 二、…

数据挖掘/深度学习-高校实训解决方案

一、解决方案架构 项目/产品 类型 介绍 云原生一站式机器学习/深度学习/大模型AI平台 AI训练开发平台 云原生一站式机器学习/深度学习/大模型AI平台&#xff0c;支持sso登录&#xff0c;多租户&#xff0c;大数据平台对接&#xff0c;notebook在线开发&#xff0c;拖拉拽任…

Leetcode 面试150题 189. 轮转数组 中等

系列博客目录 文章目录 系列博客目录189. 轮转数组 中等示例 1示例 2解答 189. 轮转数组 中等 链接 描述&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负整数。 示例 1 输入: nums [1, 2, 3, 4, 5, 6, 7], k 3…

企业如何落地搭建商业智能BI系统

随着新一代信息化、数字化技术的应用&#xff0c;引发了新一轮的科技革命&#xff0c;现代化社会和数字化的联系越来越紧密&#xff0c;数据也变成继土地、劳动力、资本、技术之后的第五大生产要素&#xff0c;这一切都表明世界已经找准未来方向&#xff0c;前沿科技也与落地并…

pyhton+yaml+pytest+allure框架封装-全局变量渲染

我们在日常测试中 会有一个接口中多个值的情况 比如这种 { "name": "thread", "value": "4986-MainThread", "status": "framework", "start": "pytest", …

Jetpack业务架构(ViewModel)

ViewModel是Jetpack AAC的重要组件&#xff0c;同时也有一个同名抽象类。 ViewModel&#xff0c;意为 视图模型&#xff0c;即为界面准备数据的模型。简单理解就是&#xff0c;ViewModel为UI层提供数据。 1ViewModel使用&#xff1a; ①思路&#xff1a; 导入依赖 继承ViewMo…

2024.11.28(作业)

思维导图 功能函数声明文件 #ifndef _FUN_H__ #define _FUN_H__ #include <myhead.h>#define MAX 50 //数组大小 #define QAZ 20 //长度和字符串大小typedef int datatype; //数据元素类型//2.1 定义顺序表类型 typedef struct {datatype data[MAX];int len; }S…