SqlAlchemy使用入门

官方文档:https://docs.sqlalchemy.org/

​  SQLAlchemy是一个Python的SQL工具ORM 框架,提供了丰富的SQL操作和数据持久化功能,支持多种数据库,包括 PostgreSQL、MySQL、Oracle、SQLite 等。SQLAlchemy分为SQL Expression Language和ORM两部分。

在这里插入图片描述

SQLAlchemy 的优缺点

优点:

  • 支持多种数据库,可以无缝切换数据库类型。
  • 提供了多种 SQL 操作和查询方式,可以灵活处理复杂的 SQL 操作和数据查询。
  • ORM功能丰富,提供了多种映射关系的方式,可以灵活处理对象和表之间的关系。
  • 支持连接池和事务管理等功能,可以提高数据库的性能和可靠性。

缺点:

  • 学习曲线较陡峭,需要一定的学习成本。
  • 代码量较多,可能会增加代码复杂度。
  • ORM 功能相对于其他 Python ORM框架而言,稍显笨重,对于简单的数据操作,可能会显得有些冗余。

模型字段

字段说明可选属性
Integer整型primary_key autoincrement
String字符串
Text文本
Float浮点型精度precision 小数位数scale
DateTime日期时间
Boolean布尔型
Enum枚举choices
JSONJSON 数据类型
ARRAY数组数据类型
BigInteger大整型
Interval时间间隔,用于存储时间差值
ForeignKey外键删除时的行为ondelete 更新时的行为onupdate
Relationship关系反向引用backref
Column是否唯一unique 是否索引index

字段属性

选项说明备注
nullable是否可为空
default默认值
primary_key是否为主键
unique是否唯一
index是否为索引
autoincrement是否自动递增
ondelete删除时的行为
onupdate更新时的行为
server_default在数据库中设置默认值
server_onupdate在数据库中设置更新时的行为

SQLAlchemy操作

​  首先我们建立用户表和文章表,其中用户和文章是一对多关系,User和Article表中的uid为逻辑外键,以下面的建立的engine和session来操作数据库。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from enum import Enum

from sqlalchemy import Column, Integer, String, Enum as EnumType, DateTime, ForeignKey, Text, create_engine
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.sql import func
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_method

Base = declarative_base()


class Gender(Enum):
    male = '男'
    female = '女'
    unknown = '未知'


class User(Base):
    __tablename__ = 't_user'

    id = Column(Integer, primary_key=True)
    name = Column(String(32), nullable=False, comment='姓名')
    gender = Column(EnumType(Gender), nullable=False, comment='性别')
    created_at = Column(DateTime, default=func.now(), nullable=False)
    updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False)

    def __str__(self):
        return self.id

    @hybrid_method
    def as_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'gender': self.gender.value,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S')
        }


class Article(Base):
    __tablename__ = 't_article'

    id = Column(Integer, primary_key=True)
    content = Column(Text, comment='文章內容')
    uid = Column(Integer, ForeignKey('t_user.id'), comment='用戶id')
    t_user = relationship("User", foreign_keys=uid)
    created_at = Column(DateTime, default=func.now(), nullable=False)
    updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False)

    def __str__(self):
        return self.id

    @hybrid_method
    def as_dict(self):
        return {
            'id': self.id,
            'content': self.content,
            'uid': self.uid,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S')
        }


engine = create_engine('postgresql://postgres:postgres@host:port/database')

Session = sessionmaker(bind=engine)
session = Session()

1、 建表

# 创建表    所有继承了Base的类
Base.metadata.create_all(engine)

2、 添加记录

添加记录使用session来对数据库进行操作。

# 添加记录 单条
user_obj = User(name='test_user_1', gender=Gender.unknown)
session.add(user_obj)
session.commit()

# 添加记录 多条
user_obj_2 = User(name='test_user_2', gender=Gender.male)
user_obj_3 = User(name='test_user_3', gender=Gender.female)
session.add_all([user_obj_2, user_obj_3])
session.commit()

3、 查询

3.1 查询结果序列化

​hybrid_method是SQLAlchemy 提供的一个装饰器,它可以将一个方法转换为一个混合属性,既可以像方法一样被调用,也可以像属性一样被访问。我们可以利用这个方法序列化字段。

# 使用示例
from sqlalchemy.ext.hybrid import hybrid_method

@hybrid_method
    def as_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'gender': self.gender.value,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S')
        }
 
users = session.query(User).all()
seria_data = [user.as_dict() for user in users]

print(seria_data)
3.2 query
users = session.query(User).all()
3.3 filter_by

filter_by直接使用关键字参数指定过滤条件,但只能使用单个条件进行查询。使用 filter_by 方法时,必须确保过滤条件的列在查询表中是唯一的,否则会引发错误。

session.query(User).filter_by(name='test_user_1').all()
3.4 filter

filter方法使用关键字参数指定查询条件,可以使用多个条件组合查询,可以处理更为复杂的查询

session.query(User).filter(User.name == 'Alice', User.id > 2).all()
3.5 order_by

用于按指定字段对查询结果进行排序

session.query(User).order_by(User.id.desc()).all()
3.6 group_by

用于按指定字段进行分组查询。

session.query(User.name, func.count(User.id)).group_by(User.name).all()
3.7 join

用于关联查询两个表

# 连表查询
result = session.query(User, Article).join(Article).all()

# 遍历查询结果
for user, article in result:
     print(user.name, article.id, article.uid)
3.8 limit

用于限制查询结果的数量。

session.query(User).order_by(User.id.desc()).limit(10).all()
3.9 offset

用于指定查询结果的偏移量

 session.query(User).order_by(User.age.desc()).offset(10).limit(10).all()
3.10 subquery

用于创建一个子查询

from sqlalchemy import select

subquery = select(User.id).filter_by(name='Alice').subquery()
session.query(Article).filter(Article.user_id.in_(subquery)).all()
3.11 distinct

用于去重查询结果

session.query(User.name).distinct().all()
3.12 having

用于对分组查询结果进行过滤。

from sqlalchemy import func

users = session.query(User.name, func.count(User.id)).group_by(User.name).having(func.count(User.id) > 1).all()
3.13 执行 SQL 原生语句

执行sql语句要避免SQL注入攻击,使用占位符 :field 和命名占位符 %来避免。

from sqlalchemy import text

# 使用占位符传递参数
session.execute(text('SELECT * FROM table WHERE id=:id'), {'id': 1})

# 使用命名占位符传递参数
session.execute(text('SELECT * FROM table WHERE id=%(id)s'), {'id': 1})

4、 获取结果

方法名含义备注
exists判断查询结果是否存在
count统计查询结果的数量
scalar获取查询结果的第一个字段
first获取查询结果的第一条记录
get根据主键获取一条记录get(pk)
one获取查询结果的唯一一条记录
all获取查询结果的所有记录
one_or_none获取查询结果的唯一一条记录查询结果为空或不唯一则返回 None
delete删除记录
update更新记录.update({‘field’: ‘val’})
scalar_subquery获取子查询的第一列第一行的值

5、 查询运算符

可以使用 and_、or_、not_ 函数来组合多个查询条件,从而实现更为复杂的查询操作

运算符含义
==等于
!=不等于
<小于
>大于
<=小于等于
>=大于等于
like模糊匹配
in_判断一个值是否在一个列表
notin_判断一个值是否不在一个列表
is_用于判断值
and_
or_

6、事务使用

在数据库操作中,事务用来保证一组相关的数据库操作在执行过程中的一致性和完整性,即要么全部执行成功,要么全部执行失败。在 SQLAlchemy 中,使用 Session 进行事务操作。

# 使用示例
with session.begin():
	    user = User(name='Alice', age=25)
	    session.add(user)

SqlAlchemy开启异步会话

  在SQLAlchemy中,可以使用async_session()方法来创建异步会话。这个方法返回一个asyncio.Task 对象,可以在异步上下文中运行。异步会话需要在异步上下文中使用,即使用 async with 异步会话工厂() as session 的方式。此外,由于异步会话是异步的,因此在调用异步会话的方法时需要使用 await 关键字。

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker

# 创建异步引擎
engine = create_async_engine('postgresql+asyncpg://user:password@host/dbname')

# 创建异步会话工厂
async_session_factory = sessionmaker(
    engine,
    expire_on_commit=False,
    class_=AsyncSession
)

# 使用异步会话
async with async_session_factory() as session:
    result = await session.execute(select(User).where(User.id == 1))
    user = result.fetchone()
    print(user)

falsk_sqlalchemy使用

  Flask-SQLAlchemy是一个基于Flask的SQLAlchemy扩展,使得在 Flask 应用中使用SQLAlchemy 更加方便。它提供了一个 SQLAlchemy 实例db,可以在 Flask 应用中使用。使用Flask-SQLAlchemy,首先需要在 Flask 应用中创建一个SQLAlchemy实例,并配置连接数据库的URI。操作session和SQLalchemy一致。

使用示例:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:postgres@host:port/database'
db = SQLAlchemy(app)

class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))
    email = db.Column(db.String(128))
    
# 创建表
 db.create_all()
    
# 添加记录
user = User(name='John', email='john@example.com')
db.session.add(user)
db.session.commit()

# 查询操作
db.session.query(User).filter_by(name='John').order_by(User.id.desc()).all()

常用的 Flask-SQLAlchemy 配置参数:

参数含义
SQLALCHEMY_DATABASE_URI数据库连接字符串
SQLALCHEMY_TRACK_MODIFICATIONS是否追踪对象的修改并发送信号
SQLALCHEMY_ECHO是否打印 SQL 语句和执行时间等调试信息
SQLALCHEMY_POOL_SIZE数据库连接池的大小,默认为 5
SQLALCHEMY_MAX_OVERFLOW连接池中最多可增加的连接数,默认为10
SQLALCHEMY_POOL_TIMEOUT获取连接的超时时间,默认为10 秒
SQLALCHEMY_POOL_RECYCLE连接池中连接的最大寿命
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
SQLAlchemy是一个Python的SQL工具和对象关系映射(ORM)库。它提供了一种将数据库中的数据映射到Python对象的方式,使得在Python代码中可以更方便地进行数据库操作。引用介绍了在使用SQLAlchemy执行SQL语句时,可以使用sqlalchemy.text来定义文本SQL字符串,并使用参数传递的方式来避免SQL注入的问题。通过使用:y的格式定义参数,并将参数值以字典的形式传给execute方法,可以安全地执行带有参数的SQL查询。引用展示了通过create_engine函数连接数据库的示例,其中使用了mysql+pymysql://作为连接字符串的前缀,并传入用户名、密码、主机和数据库名等参数。引用概述了SQLAlchemy的一些基本使用方法和功能,包括执行原生SQL查询、使用ORM进行单表操作、一对多和多对多关系的操作,以及在Flask应用中使用SQLAlchemy的方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SQLAlchemy完全入门](https://blog.csdn.net/u013190417/article/details/122402879)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [SQLAlchemy使用教程](https://blog.csdn.net/js010111/article/details/119844734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [09. SQLAlchemy介绍](https://blog.csdn.net/weixin_49111957/article/details/114106607)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楼下安同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值