Loading

hellohelp

sqlalchemy及flask-sqlalchemy的使用方法

1.sqlalchemy

  • 使用全面介绍(这种方法不推荐,推荐下边的一种方法)

    from sqlalchemy import create_engine, Column, Integer, String, DateTime, MetaData, Table
    from sqlalchemy.orm import declarative_base, sessionmaker, scoped_session
    from urllib.parse import quote_plus  # 引入这个模块,解决数据库密码中存在@导致截断的问题,对密码进行编码。
    
    raw_password = 'My@20241103'  # 原始密码
    # 对密码进行 URL 编码
    encoded_password = quote_plus(raw_password)
    # 构造安全的连接字符串
    connection_string = f"mysql+pymysql://root:{encoded_password}@localhost:3306/woniunote"
    
    # 1.连接数据库,建立连接引擎
    engine = create_engine(connection_string, echo=False, pool_size=20)  # echo为true会隐藏密码
    
    # 2.定义数据模型(ORM)
    # 2-1第一种方法
    # 定义表格数据对象的父类(里边含有表格的增删查改操作,是所有 ORM 映射类的基类)
    # Base = declarative_base()
    
    # 定义users表操作类,继承了orm基类
    # 新建表的情况
    # class Users(Base):
    #     __tablename__ = 'users'
    #
    #     # 如果需要在SQLAlchemy里面直接创建表结构,则详细定义表的列
    #     # 一般在可视化工具里边把数据表huo命令行客户端给建立好了,所以一般不在这个地方建立表的字段,所以下边的一般不用
    #     userid = Column(Integer, primary_key=True)
    #     username = Column(String(50))
    #     password = Column(String(32))
    #     nickname = Column(String(30))
    #     qq = Column(String(15))
    #     role = Column(String(10))
    #     credit = Column(Integer)
    #     createtime = Column(DateTime)
    #     updatetime = Column(DateTime)
    # 创建表
    # 在 SQLAlchemy 中,更推荐使用基类的元数据来创建所有表,而不是单个模型类
    # Base.metadata.create_all(engine)
    # 更推荐上边这种创建表的方法,Base.metadata 是所有继承自基类的模型共享的元数据容器。显式使用 Base.metadata 表明您要创建所有模型对应的表。当添加新模型时,不需要修改创建表的代码
    # Users.metadata.create_all(engine)  这种元数据建表不推荐,会被误解为只建立Users模型。
    
    # 2-2 第二种方法 表已存在,反射已有表结构
    # 自动反射现有数据库
    metadata = MetaData()
    metadata.reflect(bind=engine)
    
    # 获取已存在的表
    Base = declarative_base(metadata=metadata)
    
    # 直接使用反射的表,得到的是表对象模型
    Users = metadata.tables['users']
    Article = metadata.tables['article']
    
    
    # 3.创建会话
    Dbsession = sessionmaker(bind=engine)  # 绑定连接引擎,引入会话类
    # dbsession=Dbsession()  #1.创建会话实例
    dbsession = scoped_session(Dbsession)  # 1.创建线程安全的会话实例,多线程环境中,强烈建议使用 scoped_session。
    # 上述请求结束时需要清理(Web框架通常自动处理)dbsession.remove()  # 关闭并重置当前线程的Session.flask中在app.teardown_appcontext钩子中使用这句话销毁这个会话
    
    # 4.执行操作
    
    if __name__ == '__main__':
        # result = dbsession.query(Article).all()
        result = dbsession.query(Users).all()
        print(result)
    
    
  • 推荐使用的方法

# -*- coding: utf-8 -*-
# --------------------------------------
# 利用SQLAlchemy实现数据库orm(对象关系映射),简化数据库的操作
from sqlalchemy import create_engine, Column, Integer, String, DateTime, MetaData, Table
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import declarative_base, sessionmaker, scoped_session
from urllib.parse import quote_plus  # 引入这个模块,解决数据库密码中存在@导致截断的问题,对密码进行编码。

raw_password = 'My@20241103'  # 原始密码
# 对密码进行 URL 编码
encoded_password = quote_plus(raw_password)
# 构造安全的连接字符串
connection_string = f"mysql+pymysql://root:{encoded_password}@localhost:3306/woniunote"

# 1.连接数据库,建立连接引擎
engine = create_engine(connection_string, echo=False, pool_size=20)  # echo为true会隐藏密码

# 2.定义数据模型(ORM)
# 自动映射整个数据库
Base = automap_base()
Base.prepare(autoload_with=engine)

# # 获取映射的类,得到的是表对象映射模型  最后一个users和article是表名
Users = Base.classes.users
Article = Base.classes.article

# 3.创建会话
Dbsession = sessionmaker(bind=engine)  # 绑定连接引擎,引入会话类
# dbsession=Dbsession()  #1.创建会话实例
dbsession = scoped_session(Dbsession)  # 1.创建线程安全的会话实例,多线程环境中,强烈建议使用 scoped_session。
# 上述请求结束时需要清理(Web框架通常自动处理)dbsession.remove()  # 关闭并重置当前线程的Session.flask中在app.teardown_appcontext钩子中使用这句话销毁这个会话

# 4.执行操作

if __name__ == '__main__':
    # 1.查询第一个或全部
    # result = dbsession.query(Article).first()
    result = dbsession.query(Users).all()
    print(result[0].nickname)
    # 2.条件查询
    result = dbsession.query(Users).filter_by(username="admin").first()
    print(result.nickname)
    result = dbsession.query(Users).filter(Users.nickname.like("%浪浪山%")).all()
    print(result[0].username)
    result = dbsession.query(Users).filter(Users.userid > 1).all()
    print(result[0].username)
    # 3.获取特定列
    names = dbsession.query(Users.username).all()
    names2 = dbsession.query(Users.userid,Users.username).all()
    print(names2)
    # 4.多条件查询
    results = dbsession.query(Users).filter(
        Users.username != "Alice",
        Users.nickname.contains("浪浪山")
    ).order_by(Users.userid.desc()).limit(10).all()
    print(results)
    # 5.新增插入
    new_user = Users(username="Alice", password='234567', role="user")
    dbsession.add(new_user)
    dbsession.commit()  # 提交事务
    # 6.批量插入
    dbsession.add_all([
        Users(username="Bob", password='1234566', role="user"),
        Users(username="Charlie",  password='123456', role="user")
    ])
    dbsession.commit()
    # 7. 删除和更新
    row = dbsession.query(Users).filter_by(username="Ali").first()
    row.password = '666666'
    dbsession.commit()
    # 删除
    dbsession.query(Users).filter_by(username="Alice").delete()
    dbsession.commit()



2.flask-sqlalchemy

project/
  ├── app/
  │   ├── __init__.py     # 工厂函数
  │   ├── extensions.py   # 扩展实例
  │   ├── models/         # 模型目录
  │   ├── routes/         # 视图蓝图
  │   └── templates/
  ├── migrations/         # 数据库迁移
  └── config.py           # 配置文件

三步:创建db实例;创建模型类和操作方法;生成一个访问接口(通过路由获取这个数据表的值)

实现方式

  1. 创建数据库实例文件 (extensions.py)
# extensions.py
from flask_sqlalchemy import SQLAlchemy

# 创建未初始化的SQLAlchemy实例
db = SQLAlchemy()
  1. 模型定义文件 (models.py)
# models.py
from .extensions import db

class User(db.Model):   #(底下的字段文件通过sqlacodegen模块来生成,见底下)
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
  1. 应用初始化文件 (app.py)
# app.py
from flask import Flask
from .extensions import db
from . import models  # 确保模型被导入

def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'f"mysql+pymysql://root:My%4020241103@localhost:3306/woniunote"'
    
    # 初始化数据库
    db.init_app(app)
    
    return app

if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)
  1. 在其他文件中使用数据库
# routes.py
from flask import Blueprint, jsonify
from .extensions import db
from .models import User

api = Blueprint('api', __name__)

@api.route('/users')
def get_users():
    users = User.query.all()
    return jsonify([{'id': u.id, 'username': u.username} for u in users])

@api.route('/add-user/<name>')
def add_user(name):
    new_user = User(username=name, email=f"{name}@example.com")
    db.session.add(new_user)
    db.session.commit()
    return f"Added user {name}!"

关键点说明

  1. 跨文件使用

    • 任何需要操作数据库的文件只需:

      from .extensions import db
      from .models import User  # 或其他模型
      

💎使用sqlacodegen获取模型实例:(自动生成表模型文件)

Terminal里输入命令:

 sqlacodegen mysql+pymysql://root:My%4020241103@localhost/woniunote --tables users,article > models.py

调整模型文件models.py(替换 Basedb.Model):

一个生成的例子(这个文件的表模型还可以封装其他方法):

# 数据库表模型  sqlacodegen mysql+pymysql://root:My%4020241103@localhost/woniunote --tables users,article > model.py 获取表模型
import datetime
from typing import Optional

from sqlalchemy import Integer, String, text, DateTime
from sqlalchemy.orm import Mapped, mapped_column


from woniu_note.extensions import db


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

    userid: Mapped[int] = mapped_column(Integer, primary_key=True)
    username: Mapped[str] = mapped_column(String(50))
    password: Mapped[str] = mapped_column(String(32))
    role: Mapped[str] = mapped_column(String(10), server_default=text("'user'"))
    credit: Mapped[int] = mapped_column(Integer, server_default=text("'50'"))
    nickname: Mapped[Optional[str]] = mapped_column(String(30))
    avatar: Mapped[Optional[str]] = mapped_column(String(20))
    qq: Mapped[Optional[str]] = mapped_column(String(15))
    createtime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime)
    updatetime: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime)

    # 这里边还可以封装其他方法如:
    # def find_user_by_id(self, userid):
    #     row = db.session.query(Users).filter(Users.userid == userid).first()
    #     return row
posted @ 2025-08-14 23:29  HordorZzz  阅读(21)  评论(0)    收藏  举报