1.数据库的连接、创建会话与模型

· 浏览次数 : 8

小编点评

SQLAlchemy 是一个用于操作数据库的 Python 库,它提供了一种面向对象的方式来处理数据库操作。在本教程中,我们将了解 SQLAlchemy 的基础知识,包括其与传统执行 SQL 和 ORM 的区别。 1. 传统执行 SQL 传统执行 SQL 是指直接使用 SQL 语句与数据库进行交互。这种方式具有较高的灵活性,但需要手动编写 SQL 语句并管理数据库连接、事务处理等。以下是一个简单的示例: ```python import pymysql # 连接数据库 connection = pymysql.connect(host='localhost', user='root', password='0908', database='db_flask_demo_school', charset='utf8mb4') try: with connection.cursor() as cursor: # 执行 SQL 查询 sql = "SELECT * FROM tb_student" cursor.execute(sql) result = cursor.fetchall() for row in result: print(row) finally: connection.close() ``` 2. ORM(对象关系映射) ORM 是一种通过面向对象的方式来操作数据库的技术。ORM 将数据库表映射为类,将表中的记录映射为类的实例,使得你可以用面向对象的方式来进行数据库操作。以下是一个简单的示例: ```python from sqlalchemy import create_engine, Column, Integer, String, Boolean from sqlalchemy.orm import declarative_base, sessionmaker # 创建数据库引擎 engine = create_engine('mysql+pymysql://root:0908@localhost:3306/db_flask_demo_school?charset=utf8mb4') Base = declarative_base() # 定义模型 class Student(Base): __tablename__ = 'tb_student' id = Column(Integer, primary_key=True, comment='学生编号') name = Column(String(20), comment='学生姓名') sex = Column(Boolean, default=True, comment='学生性别') age = Column(Integer) # 创建会话 SessionLocal = sessionmaker(bind=engine) session = SessionLocal() # 查询数据 students = session.query(Student).all() for student in students: print(student.name) ``` 比较特性: - 传统执行 SQL:适用于需要精细控制 SQL 查询的场景,或者需要使用复杂的 SQL 特性的场景。 - ORM:适用于需要快速开发、代码可读性和维护性要求高的场景。 总结: SQLAlchemy 提供了一种更高级的数据库操作方式,通过面向对象的方式简化了数据库操作。在实际开发中,可以根据需求选择使用 SQLALchemy 或者继续使用传统执行 SQL。

正文

SQLAlchemy 是一个强大的 Python 库,它让你可以用一种面向对象的方式来操作数据库(ORM 技术)。

在学习 SQLAlchemy 的过程中,需要一些基础知识的沉淀:Python基础、Python面向对象、MySQL数据库的诸多知识点……

在此之前,你可能需要了解传统执行SQL语句和使用ORM的一些区别以及他们的概念。

什么是传统执行 SQL?

传统执行 SQL 是指直接使用 SQL 语句与数据库进行交互。这通常包括连接数据库、编写 SQL 查询、执行查询以及处理结果。

特点

  1. 直接编写 SQL 语句:你需要手动编写 SQL 查询来操作数据库。
  2. 灵活性高:可以使用所有的 SQL 功能,精确控制查询和操作。
  3. 低级别控制:你需要管理数据库连接、事务处理等。

示例

import pymysql

# 连接数据库
connection = pymysql.connect(
    host='localhost',
    user='root',
    password='0908',
    database='db_flask_demo_school',
    charset='utf8mb4'
)

try:
    with connection.cursor() as cursor:
        # 执行 SQL 查询
        sql = "SELECT * FROM tb_student"
        cursor.execute(sql)
        result = cursor.fetchall()
        for row in result:
            print(row)
finally:
    connection.close()

什么是 ORM(对象关系映射)?

ORM 是一种通过面向对象的方式来操作数据库的技术。ORM 将数据库表映射为类,将表中的记录映射为类的实例,使得你可以用面向对象的方式来进行数据库操作。

特点

  1. 面向对象:使用类和对象来表示数据库表和记录。
  2. 自动生成 SQL:ORM 框架会根据你的操作自动生成相应的 SQL 语句。
  3. 简化代码:简化了数据库操作的代码,使得代码更易读、更易维护。

示例

from sqlalchemy import create_engine, Column, Integer, String, Boolean
from sqlalchemy.orm import declarative_base, sessionmaker

# 创建数据库引擎
engine = create_engine('mysql+pymysql://root:0908@localhost:3306/db_flask_demo_school?charset=utf8mb4')
Base = declarative_base()

# 定义模型
class Student(Base):
    __tablename__ = 'tb_student'
    id = Column(Integer, primary_key=True)
    name = Column(String(20))
    sex = Column(Boolean, default=True)
    age = Column(Integer)

# 创建会话
SessionLocal = sessionmaker(bind=engine)
session = SessionLocal()

# 查询数据
students = session.query(Student).all()
for student in students:
    print(student.name)

比较

特性 传统执行 SQL ORM
编写 SQL 语句 手动编写 自动生成
操作方式 直接操作数据库 面向对象操作
灵活性 高,完全控制 SQL 语句 中等,受限于 ORM 框架
代码简洁性 代码较冗长 代码简洁易读
学习曲线 需要掌握 SQL 语法 需要学习 ORM 框架的用法
性能 可能更高效,具体取决于 SQL 语句 可能稍慢,但差异通常不明显
维护性 低,SQL 语句分散在代码中 高,结构清晰,易于维护

适用场景

  • 传统执行 SQL:适用于需要精细控制 SQL 查询的场景,或者需要使用复杂的 SQL 特性的场景。
  • ORM:适用于需要快速开发、代码可读性和维护性要求高的场景。ORM 可以大大简化常见的数据库操作。

接下来进入 SQLAlchemy 的快速学习

1. 创建数据库驱动引擎

首先,我们需要创建一个数据库驱动引擎。当你连接数据库时,需要提前创建这个数据库。

CREATE DATABASE db_flask_demo_school CHARSET=utf8mb4

这个引擎就是你和数据库之间的桥梁。

from sqlalchemy import create_engine

engine = create_engine(
    # url = '驱动://账户:密码@地址:端口/数据库名?charset=编码'
    url='mysql+pymysql://root:0908@localhost:3306/db_flask_demo_school?charset=utf8mb4',
    echo=True,  # 在控制台输出SQL语句,方便调试
    pool_size=8,  # 连接池的数据库连接数量
    max_overflow=30,  # 连接池的数据库连接最大数量
    pool_recycle=60 * 30,  # 设置秒数限制数据库多久没连接自动断开
)

2. 创建数据库会话

有了引擎之后,我们需要创建一个会话,这样才能和数据库进行交互。会话就像是你和数据库之间的对话窗口。

from sqlalchemy.orm import sessionmaker

SessionLocal = sessionmaker(bind=engine)  # 工厂函数,创建新的会话类
session = SessionLocal()  # 实例化。用于与数据库进行交互

另一种创建会话的方式

from sqlalchemy.orm import Session

# 目前官方文档上的案例使用的这种
# 大多数机构教学或者旧的学习资料中可能是上述方式
session = Session(bind=engine)

3. 定义模型基类

在 SQLAlchemy 中,模型是与数据库表对应的类。我们需要定义一个基类,所有的模型都将继承这个基类。

from sqlalchemy.orm import declarative_base

Model = declarative_base()

另一种创建基类的方式

from sqlalchemy.orm import DeclarativeBase

class Model(DeclarativeBase):
    pass

该方式也是来源于目前官方文档的示例。

4. 创建模型

现在我们基于上方的模型基类,创建一个学生模型,这个模型对应数据库中的 tb_student 表。

每个模型类对应的其实就是数据库中的表,其中表名、字段都对应了类属性的设置,而每个类的实例对象也就是一条记录。

import db
import datetime

class Student(db.Model):
    __tablename__ = 'tb_student'  #  数据表的名字
    # db.Column 是一个字段对象,对应表字段,接受很多很多的参数(没啥好记的,浪费大脑为数不多的空间,参见末尾的表),常用字段属性是字段类型、是否为主键、备注描述、默认值指定等等
    # 整型 + 主键 + 告知这是学生编号(默认自增)
    id = db.Column(db.Integer, primary_key=True, comment='学生编号')
    # 20位字符串 + 告知这是学生姓名
    name = db.Column(db.String(20), comment='学生姓名')
    # 布尔型(实际上存储是0或1),默认是 True(存储是1)
    sex = db.Column(db.Boolean, default=True, comment='学生性别')
    # 精度更小的整型
    age = db.Column(db.SmallInteger, comment='学生年龄')
    # 'class' 这里不是类型,而是别名,因为 class = xxx,在python中是不行的(关键字)
    class_ = db.Column('class', db.SMALLINT, comment='学生班级')
    # 文本类型
    description = db.Column(db.Text, comment='个性签名')
    # 布尔型,默认值也可以写成 1
    status = db.Column(db.Boolean, default=1, comment='登录状态')
    # 日期时间类型,默认值需要特别注意,引用了 datetime 库,使用的是 now函数的地址,而不是它的调用结果。如果使用调用结果,将以项目执行启动的时间为准
    addtime = db.Column(db.DateTime, default=datetime.datetime.now, comment='入学时间')
    orders = db.Column(db.SMALLINT, default=1, comment='学生排序')

    def __repr__(self):
        # 便于打印列表时,显示 [ <Student: 老王(12)>,...]
        return f'<{self.__class__.__name__}: {self.name}({self.id})>'

    def to_dict(self):
        # 便于对象直接转成字符串,实现方式很多,比如 __dict__ 拷贝一份,然后筛选非'_'字符开头的键也行。
        return {
            'id': self.id,
            'name': self.name,
            'sex': self.sex,
            'age': self.age,
            'class': self.class_,
            'description': self.description,
            'status': self.status,
            'addtime': self.addtime.strftime('%Y-%m-%d %H:%M:%S'),  # 需要注意获取到的是 DateTime 对象,参见 datetime 库
            'orders': self.orders,
        }

if __name__ == '__main__':
    # 建表操作,如果如果你所在的公司或者团队或者你自身负责数据库的设计(DBA),那么建表无需执行 create_all
    # 当然,也有一些坑13,如果没有为你建表甚至没有设计,emmmm……,那就自己来吧!
    db.Model.metadata.create_all(db.engine)

附表:常用 Column 字段

下面是一个详细的 SQLAlchemy Column 类型及其参数的表格,包括字段的用途、存储到数据库的类型、Python 中表示的数据类型等信息。

字段类型 参数示例 用途 数据库类型 Python 类型
Integer Column(Integer, primary_key=True) 存储整数 INTEGER int
String Column(String(50), nullable=False) 存储字符串 VARCHAR str
Text Column(Text) 存储大文本数据 TEXT str
Boolean Column(Boolean, default=True) 存储布尔值 BOOLEAN bool
DateTime Column(DateTime, default=datetime.datetime.now) 存储日期和时间 DATETIME datetime.datetime
Float Column(Float) 存储浮点数 FLOAT float
SmallInteger Column(SmallInteger) 存储小范围整数 SMALLINT int
LargeBinary Column(LargeBinary) 存储二进制数据 BLOB bytes
Numeric Column(Numeric(10, 2)) 存储精确的小数 NUMERIC decimal.Decimal
Date Column(Date) 存储日期 DATE datetime.date
Time Column(Time) 存储时间 TIME datetime.time
Enum Column(Enum('value1', 'value2')) 存储枚举值 ENUM enum.Enum
Interval Column(Interval) 存储时间间隔 INTERVAL datetime.timedelta
JSON Column(JSON) 存储 JSON 数据 JSON dict
UUID Column(UUID(as_uuid=True)) 存储 UUID UUID uuid.UUID
ARRAY Column(ARRAY(String)) 存储数组 ARRAY list
JSONB Column(JSONB) 存储 JSONB 数据(PostgreSQL) JSONB dict
HSTORE Column(HSTORE) 存储键值对(PostgreSQL) HSTORE dict
INET Column(INET) 存储 IP 地址(PostgreSQL) INET str
CIDR Column(CIDR) 存储 IP 地址范围(PostgreSQL) CIDR str
MACADDR Column(MACADDR) 存储 MAC 地址(PostgreSQL) MACADDR str

常用 Column 参数

  • primary_key:是否为主键。
    • 类型bool
    • 默认值False
    • 示例Column(Integer, primary_key=True)
  • nullable:是否允许为空。
    • 类型bool
    • 默认值True
    • 示例Column(String, nullable=False)
  • default:默认值。
    • 类型any
    • 默认值None
    • 示例Column(Boolean, default=True)
  • unique:是否唯一。
    • 类型bool
    • 默认值False
    • 示例Column(String, unique=True)
  • index:是否创建索引。
    • 类型bool
    • 默认值False
    • 示例Column(String, index=True)
  • comment:字段注释。
    • 类型str
    • 默认值None
    • 示例Column(String, comment='用户名')
  • autoincrement:是否自动递增(通常用于主键)。
    • 类型boolstr(好像是auto表示自增吧,忘记了,可查文档)
    • 默认值True(在主键列上)
    • 示例Column(Integer, primary_key=True, autoincrement=True)
  • server_default:数据库服务器端的默认值。
    • 类型DefaultClausestr
    • 默认值None
    • 示例Column(String, server_default='default_value')
  • server_onupdate:数据库服务器端的更新值。
    • 类型DefaultClausestr
    • 默认值None
    • 示例Column(DateTime, server_onupdate=func.now())
  • onupdate:更新时的默认值。
    • 类型any
    • 默认值None
    • 示例Column(DateTime, onupdate=datetime.datetime.now)
  • foreign_key:外键约束。
    • 类型ForeignKey
    • 默认值None
    • 示例Column(Integer, ForeignKey('other_table.id'))

与1.数据库的连接、创建会话与模型相似的内容:

1.数据库的连接、创建会话与模型

SQLAlchemy 是一个强大的 Python 库,它让你可以用一种面向对象的方式来操作数据库(ORM 技术)。 在学习 SQLAlchemy 的过程中,需要一些基础知识的沉淀:Python基础、Python面向对象、MySQL数据库的诸多知识点…… 在此之前,你可能需要了解传统执行SQL语句和使

SQLAlchemy - 模块文件以及增删改查(CURD操作)

创建 db.py db.py 文件是我们管理数据库连接和模型基类的地方。它让我们的代码更加模块化和可维护,实际生产中也是类似的,无论是在 FastAPI 或者 Flask 等框架中,当使用到 SqlAlchemy 时,的的确确需要一个单独 db.py,存储着引擎、会话以及模型基类。这个文件请务必建好

.NET6项目连接数据库方式方法

前言 接上一篇Linux系统下创建dotnet项目,这一篇我们聊聊.NET6环境下dotnet项目连接数据库的方式方法,包括数据库字符串该如何配置。看了很多博主写的文章,连接数据库字符串配置的方式和位置五花八门,这篇文章给大家介绍一下连接数据库字符串的配置方式方法,顺便介绍下一个新创建的dotnet

MongoDB从入门到实战之MongoDB工作常用操作命令

前言: 上一章节我们快速的在Docker容器中安装了MongoDB,并且通过Navicat MongoDB可视化管理工具快速的连接、创建数据库、集合以及添加了文档数据源。这一章节我们主要是了解一下在日常工作中MongoDB一些常用的操作命令。 MongoDB从入门到实战的相关教程 MongoDB从入

Python史上最全种类数据库操作方法,你能想到的数据库类型都在里面!甚至还有云数据库!

本文将详细探讨如何在Python中连接全种类数据库以及实现相应的CRUD(创建,读取,更新,删除)操作。我们将逐一解析连接MySQL,SQL Server,Oracle,PostgreSQL,MongoDB,SQLite,DB2,Redis,Cassandra,Microsoft Access,El

go项目实现mysql接入以及web api

本文为博主原创,转载请注明出处: 创建go项目,并在go项目中接入mysql,将mysql的配置项单独整理放到一个胚子和文件中,支持项目启动时,通过加载配置文件中的值,然后创建数据库连接。 之后使用net/http相关的库,创建路由,并在路由中通过不同的http方法,实现mysql连接的test数据

使用EF 连接 数据库 SQLserver、MySql 实现 CodeFirst

1.新建项目,下载Nuget安装包 创建项目需要注意几点,如果是基于 .net framework 的项目 需要选择 相应版本的 EF, 如果是跨平台则选择EF Core版本。 我这里选择的是 .net framework 版本。红框里面是 实现EF Code First 需要的包。 对应的版本:

.NET6 + EF Core + MySQL 创建实体和数据库、EFCore 数据迁移

前言 接上期文章《.NET6项目连接数据库方式方法》,有人问了我几个问题,现在就这几个问题,拓展延申一下创建实体类、数据库。把ORM框架和数据迁移都写进去。 安装ORM框架,这里我们采用EFCore 安装EFCore 我的项目是在Linux上创建的,使用的是vscode开发工具远程开发。为了方便大家

腾讯云 BI 数据分析与可视化的快速入门指南

通过本文的介绍,我们了解了腾讯云 BI 这款商业智能解决方案的基本功能和应用场景。从创建项目、连接数据源、数据表建模到页面搭建和推送功能的设置,我们通过一个互联网运营看板的案例,展示了如何快速入门并利用腾讯云 BI 进行数据分析和可视化。通过简单的数据编辑,我们可以轻松地设计报表,并实现数据的可视化...

Azure Data Factory(八)数据集验证之服务主体(Service Principal)

一,引言 如下图所示,今天我们接着上一篇内容,继续讲解 Azure Data Factory 中的数据集连接服务的认证方式:Service Principal 关于 Service Principal 的创建 可以参考:Azure AD(四)知识补充-服务主体 至于需要给 Service Princ