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

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

时间:2024-07-03 23:52:44浏览次数:16  
标签:Column 创建 数据库 db 会话 SQL 默认值 True

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'))

标签:Column,创建,数据库,db,会话,SQL,默认值,True
From: https://www.cnblogs.com/gupingan/p/18282769

相关文章

  • Day31.管理员创建老师功能
    1.管理员创建老师功能_代码及执行流程2.管理员创建老师功能_视图层管理员创建老师admin.py下的create_teacher方法'''管理员视图'''frominterfaceimportadmin_interfacefromlibimportcommon,common_interface#todo管理员创建老师@common.auth('admin')defc......
  • C++文件系统操作2 - 跨平台实现文件夹的创建和删除
    1.关键词2.fileutil.h3.fileutil.cpp4.filesystem_win.h5.filesystem_win.cpp6.filesystem_unix.cpp7.源码地址1.关键词C++文件系统操作创建文件夹创建多级目录文件夹删除文件夹删除文件夹下的所有文件和子目录跨平台2.fileutil.h#pragmaonce#incl......
  • 像学Excel 一样学 Pandas系列-创建数据分析维度
    嗨,小伙伴们。又到喜闻乐见的Python数据分析王牌库Pandas的学习时间。按照数据分析处理过程,这次轮到了新增维度的部分了。老样子,我们先来回忆一下,一个完整数据分析的过程,包含哪些部分内容。其中,Pandas的基础信息导入、数据导入和数据整理、数据探索和清洗已经在前几篇文章......
  • 不同系统间数据交换要通过 api 不能直接数据库访问
    很多大数据开发提供数据给外部系统直接给表结构,这是不好的方式。在不同系统间进行数据交换时,通过API(应用程序编程接口)而非直接访问数据库是现代系统集成的一种最佳实践。目录为什么要通过API进行数据交换如何通过API进行数据交换实现步骤使用Flask构建RESTfulAPI安装F......
  • Day31.管理员创建学校
    1.管理员创建学校_代码执行流程2.管理员创建学校_视图层admin.py'''管理员视图'''frominterfaceimportadmin_interfacefromlibimportcommon,common_interface#todo管理员创建学校@common.auth('admin')defcreate_school():print('管理员创建......
  • Day31.管理员创建课程功能
    1.管理员创建课程_代码及执行流程2.管理员创建课程_管理员创建课程admin.py#todo管理员创建课程@common.auth('admin')defcreate_course():print('管理员创建课程...')whileTrue:#todo1.让管理员先选择学校#todo1.1调用接口,获取所有......
  • 【漏洞复现】金斗云 HKMP智慧商业软件 任意用户创建漏洞
    0x01产品简介金斗云智慧商业软件是一款功能强大、易于使用的智慧管理系统,通过智能化的管理工具,帮助企业实现高效经营、优化流程、降低成本,并提升客户体验。无论是珠宝门店、4S店还是其他零售、服务行业,金斗云都能提供量身定制的解决方案,助力企业实现数字化转型和智能化升......
  • 车载测试之-CANoe创建仿真工程
    在现代汽车工业中,车载测试是确保车辆电子系统可靠性和功能性的关键环节。而使用CANoe创建仿真工程,不仅能够模拟真实的车辆环境,还能大大提升测试效率和准确性。那么,CANoe是如何实现这些的呢?车载测试中,为什么选择使用CANoe创建仿真工程?它具备哪些独特的功能和优势,能够在复杂的车......
  • CANoe创建仿真工程
    在现代汽车工业中,车载测试是确保车辆电子系统可靠性和功能性的关键环节。而使用CANoe创建仿真工程,不仅能够模拟真实的车辆环境,还能大大提升测试效率和准确性。那么,CANoe是如何实现这些的呢? 车载测试中,为什么选择使用CANoe创建仿真工程?它具备哪些独特的功能和优势,能够在复杂的......
  • SQLServer数据库批量kill会话的脚本(慎用!)
    微软大佬提供的一个批量kill会话的脚本,很凶很暴力,慎用慎用慎用!尤其是涉及大事务时。請注意:如果資料庫還在正在Recovery階段無效,因為無法Kill系統Session,必須等候Recovery完畢(或是重建交易紀錄檔案)。/*Function:KillallSPIDonspecificdatabaseandRepairWri......