【Flask】ORM模型以及数据库迁移的两种方法(flask-migrate、Alembic)
ORM模型
在Flask中,ORM(Object-Relational Mapping,对象关系映射)模型是指使用面向对象的方式来操作数据库的编程技术。它允许开发者使用Python类和对象来操作数据库,而不需要直接编写SQL语句。
核心概念
1. ORM模型定义
在Flask中,ORM模型通常是通过SQLAlchemy(最流行的Python ORM工具)或类似的库来定义的。一个ORM模型对应数据库中的一个表。
from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class User(db.Model):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)def __repr__(self):return f'<User {self.username}>'
2. 主要特点
-
表映射为类:每个数据库表对应一个Python类
-
列映射为属性:表中的列对应类的属性
-
行映射为对象:表中的每一行数据对应类的一个实例
常用字段类型
ORM类型 | Python类型 | 数据库类型 |
---|---|---|
db.Integer | int | INTEGER |
db.String(size) | str | VARCHAR(size) |
db.Text | str | TEXT |
db.Float | float | FLOAT |
db.Boolean | bool | BOOLEAN |
db.DateTime | datetime.datetime | DATETIME |
db.Date | datetime.date | DATE |
db.Time | datetime.time | TIME |
db.LargeBinary | bytes | BLOB |
模型关系
1. 一对多关系
class User(db.Model):id = db.Column(db.Integer, primary_key=True)posts = db.relationship('Post', backref='author', lazy=True)class Post(db.Model):id = db.Column(db.Integer, primary_key=True)user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
2. 多对多关系
tags = db.Table('tags',db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True),db.Column('post_id', db.Integer, db.ForeignKey('post.id'), primary_key=True)
)class Post(db.Model):id = db.Column(db.Integer, primary_key=True)tags = db.relationship('Tag', secondary=tags, lazy='subquery',backref=db.backref('posts', lazy=True))class Tag(db.Model):id = db.Column(db.Integer, primary_key=True)
基本CRUD操作
1. 创建(Create)
new_user = User(username='john', email='john@example.com')
db.session.add(new_user)
db.session.commit()
2. 读取(Read)
# 获取所有用户
users = User.query.all()# 获取单个用户
user = User.query.get(1)# 条件查询
user = User.query.filter_by(username='john').first()
3. 更新(Update)
user = User.query.get(1)
user.email = 'new@example.com'
db.session.commit()
4. 删除(Delete)
user = User.query.get(1)
db.session.delete(user)
db.session.commit()
在Flask中使用ORM模型
-
首先需要配置数据库URI:
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
-
创建数据库表:
with app.app_context():db.create_all()
优势
-
提高开发效率:不用写原生SQL语句
-
代码更易维护:数据库操作以面向对象方式进行
-
数据库无关性:可以轻松切换不同类型的数据库
-
安全性:自动处理SQL注入等安全问题
注意事项
-
记得在修改模型后执行数据库迁移(如使用Alembic)
-
批量操作时注意性能(N+1查询问题)
-
复杂的查询可能还是需要直接使用SQL
Flask中的ORM模型大大简化了数据库操作,使得开发者可以更专注于业务逻辑的实现。
创建外键
查询外键
Flask连接MySQL数据库+ORM增删改查
在Flask中,很少会使用pymysql直接写原生SQL语句去操作数据库,更多的是通过SQLAichemy提供的ORM技术,类似于操作普通Python对象一样实现数据库的增删改查操作,而Flask-SQLAlchemy是需要单独安装的,因为Flask-SQLAlchemy依赖SQLAlchemy,所以只要安装了Flask-SQLAlchemy,SQLAlchemy会自动安装。
pip install flask-sqlalchemy
# 登录数据库
mysql -u root -p
# 创建数据库(支持中文)
CREATE DATABASE database_learn DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import textapp=Flask(__name__)# 设置连接数据库的信息
HOSTNAME='127.0.0.1'
PORT=3306
USERNAME='root'
PASSWORD='123456'
DATABASE='database_learn'# 设置连接数据库的URL
app.config['SQLALCHEMY_DATABASE_URI']=f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4'# 在app.config中设置好连接数据库的信息,然后使用SQLLichemy(app)创建一个db对象
# SQLAlchemy会自动读取app.config中连接数据库的信息db=SQLAlchemy(app)with app.app_context():with db.engine.connect() as conn:result=conn.execute(text("select 1"))print(result.fetchone())@app.route('/')
def hello_world():return 'Hello World!'if __name__ == '__main__':app.run(debug=True)
一个ORM模型与一个数据库中的一张表对应
创建数据库表
其实就是创建一个ORM模型,而且user表有属性是username和password

添加用户
查询用户
我刷新了两次add页面,所以有两个添加张三
更新用户
删除
Flask-migrate使用方法指南
# flask-migrate迁移ORM模型
在终端中
pip install flask-migrate
flask db init
flask db migrate
flask db upgrade
自动生成。第一次创建的时候需要Init,后面再更新的话只需要后两条命令
这样就不需要再重新创建表设计表,能够直接更新表的属性
Alembic 使用方法指南
Alembic 是一个轻量级的数据库迁移工具,专门为 SQLAlchemy 设计。以下是 Alembic 的基本使用方法:
1. 安装
pip install alembic
2. 初始化
在项目目录中初始化 Alembic:
alembic init alembic
这会创建一个 alembic
目录和 alembic.ini
配置文件。
3. 配置
编辑 alembic.ini
文件,设置数据库连接:
sqlalchemy.url = driver://user:pass@localhost/dbname
或者在 alembic/env.py
中动态配置:
config.set_main_option('sqlalchemy.url', 'your-database-url')
4. 创建迁移脚本
自动生成迁移脚本(基于模型变更):
alembic revision --autogenerate -m "描述信息"
手动创建空迁移脚本:
alembic revision -m "描述信息"
5. 编辑迁移脚本
生成的迁移脚本位于 alembic/versions/
目录下,包含 upgrade()
和 downgrade()
函数。
6. 执行迁移
升级到最新版本:
alembic upgrade head
升级到特定版本:
alembic upgrade <版本号>
降级到特定版本:
alembic downgrade <版本号>
7. 其他常用命令
-
查看当前版本:
alembic current
-
查看历史记录:
alembic history
-
生成 SQL 而不执行(用于检查):
alembic upgrade head --sql
8. 与 Flask 集成
如果使用 Flask-SQLAlchemy,可以在 env.py
中:
from myapp import db
target_metadata = db.metadata
9. 最佳实践
-
每次模型变更后生成新的迁移脚本
-
为每个迁移编写清晰的描述信息
-
在团队中共享迁移脚本
-
在生产环境部署前测试迁移
注意事项
-
确保模型与数据库同步
-
自动生成迁移后检查生成的脚本是否正确
-
对于复杂变更,可能需要手动编辑迁移脚本
希望这个指南能帮助你开始使用 Alembic 进行数据库迁移管理!
相关文章:
【Flask】ORM模型以及数据库迁移的两种方法(flask-migrate、Alembic)
ORM模型 在Flask中,ORM(Object-Relational Mapping,对象关系映射)模型是指使用面向对象的方式来操作数据库的编程技术。它允许开发者使用Python类和对象来操作数据库,而不需要直接编写SQL语句。 核心概念 1. ORM模型…...
信息安全导论 第八章 入侵检测技术
目录 一、入侵检测系统概述 二、入侵检测技术 三、入侵检测系统实例 1. Snort简介 2. Snort架构 3. Snort规则示例 4. 检测流程 四、入侵防御系统 1. IPS vs. IDS 2. IPS分类 3. IPS核心技术 4. IPS优势 5.总结 一、入侵检测系统概述 定义 检测、识别和隔离对系统…...
每日c/c++题 备战蓝桥杯(P1886 滑动窗口 /【模板】单调队列)
洛谷P1886 滑动窗口【模板】单调队列详解 题目描述 给定一个长度为n的整数序列,要求输出所有长度为k的连续子数组的: 最小值(第一部分输出)最大值(第二部分输出) 数据范围: 1 ≤ k ≤ n ≤…...
GStreamer开发笔记(三):测试gstreamer/v4l2+sdl2/v4l2+QtOpengl打摄像头延迟和内存
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/147714800 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、O…...
Level DB --- MergingIterator
MergingIterator 是 Level DB中重要的类,在某一个level做多个file数据Compaction的时候,这多个file之间数据如何高效的组织和比较,这个时候用到了MergingIterator。 关键member & member function MergingIterator继承了Iterator&#…...
第六章 流量特征分析-蚁剑流量分析(玄机靶场系列)
先分享几个在Wireshark中好用的几个指令: 显示 POST 请求:http.request.method "POST",用于显示所有 POST 请求的 HTTP 数据包。显示 GET 请求:http.request.method "GET",仅显示包含 GET 请求…...
Redis数据结构ZipList,QuickList,SkipList
目录 1.ZipList 1.2.解析Entry: 1.3Encoding编码 1.4.ZipList连锁更新问题 2.QuickList SkipList跳表 RedisObject 五种数据类型 1.ZipList redis中的ZipList是一种紧凑的内存储存结构,主要可以节省内存空间储存小规模数据。是一种特殊的双端链表…...
Cordova开发自定义插件的方法
Cordova开发自定义插件的方法 文章目录 Cordova开发自定义插件的方法[TOC](文章目录) 一、自定义插件二、android下的自定义插件开发(一)步骤1、建立cordova工程2、建立自定义插件(1) 安装plugman(2) 用plu…...
Dify框架面试内容整理-如何评估基于Dify开发的AI应用的效果?
评估基于 Dify 开发的 AI 应用效果,需要从 用户体验、技术性能 与 业务价值 三个层面综合衡量。以下是详细的评估框架,涵盖三个关键点: 用户反馈与满意度...
基于python的哈希查表搜索特定文件
Python有hashlib库,支持多种哈希算法,比如MD5、SHA1、SHA256等。通常SHA256比较安全,但MD5更快,但可能存在碰撞风险,得根据自己需求决定。下面以SHA256做例。 import hashlib import os from typing import Dict, Lis…...
XZ03_Overleaf使用教程
一.Overleaf简介 Overleaf 是一款基于云端的 LaTeX 协作编辑平台,专为学术写作、技术文档和出版场景设计。以下从核心技术、功能特性、架构设计、应用场景、商业模式到未来发展趋势进行全方位解析,帮助您深度理解其核心价值与技术逻辑。 Overleaf 核心定…...
Ubuntu K8S(1.28.2) 节点/etc/kubernetes/manifests 不存在
Ubuntu K8S(1.28.2) 节点/etc/kubernetes/manifests 不存在 在查看日志(journalctl -xefu kubelet)时发现各节点/etc/kubernetes/manifests 不存在,但主节点没有异常 21080 file.go:104] "Unable to read config path" err"…...
【Linux网络#17】TCP全连接队列与tcpdump抓包
一、TCP 相关实验 测试 1. Listen 的第二个参数 LISTEN(2) Linux Programmers Manual NAMElisten - listen for connections on a socketSYNOPSIS#include <sys/types.h&g…...
JVM——Java对象的内存布局
Java对象的内存布局 在Java程序中,对象的内存布局是一个关键的底层概念。它不仅影响着对象的创建、使用和销毁的效率,也对垃圾回收、并发控制等机制有着深远的影响。下面我们将深入探讨Java对象的内存布局,包括对象的构成、内存分配、压缩指…...
USB资料摘录for后期,bus hound使用
一、STM32F105 USB调试:专家级错误分析与调试技巧: 在实时操作系统(RTOS)中进行USB调试时,开发者需要考虑任务调度、中断优先级和资源共享等问题。STM32F105在支持RTOS的环境中调试USB,应重点分析USB驱动与RTOS内核之间的交互,以及如何避免可能的竞态条件。 在商业级应用…...
防止交叉验证中的数据泄露:提升模型在实际环境中的性能
防止交叉验证中的数据泄露:提升模型在实际环境中的性能 你刚刚完成了一个机器学习模型的训练,其验证准确率达到了95%。交叉验证结果显示性能稳定,项目相关方对此表示认可,正准备将模型部署到生产环境。但是现实情况却令人沮丧——…...
Debezium TableSchemaBuilder详解
Debezium TableSchemaBuilder详解 1. 类的作用与功能 1.1 核心作用 TableSchemaBuilder是Debezium中负责构建表Schema的核心类,主要功能包括: Schema构建:将数据库表结构转换为Kafka Connect的Schema定义主键处理:生成表的主键Schema值Schema处理:生成表的非主键字段Sc…...
25:三大分类器原理
1.分类的逻辑; 2.统计学与数据分析。 ************************ Mlp 多层感知系统 GMM 高斯混合模型-极大似然估计法 SVM 支持向量机建立一个超平面作为决策曲面,使得正例和反例的隔离边界最大化 Knn 1.MLP整个模型就是这样子的,上面…...
osquery在网络安全入侵场景中的应用实战(二)
背景 上次写了osquery在网络安全入侵场景中的应用实战(一)结果还不错,这次篇目二再增加一些场景。osquery主要解决的时员工被入侵之后电脑该如何溯源取证的问题。通常EDR会有日志,但是不会上报全量的日志。发现机器有恶意文件需要上级取证的时候,往往是比较麻烦的,会有这…...
排序用法(Arrays.sort)
排序范围: 对 res 数组中索引从 0到4 的行进行排序(因为结束索引5不包含)相当于排序 res[0] 到 res[4] 这5行 比较规则: o1 和 o2 是二维数组中的两行(如 [8,2] 和 [6,7])o1[0] - o2[…...
2025年最新Linux的Redis主从集群搭建
一:概述 Redis(Remote Dictionary Server)是一个开源的、高性能的键值存储系统,通常被用作数据库、缓存或消息中间件。它以内存存储为主,支持多种数据结构,并具备持久化、高可用、分布式等特性,…...
Oracle OCP认证考试考点详解083系列09
题记: 本系列主要讲解Oracle OCP认证考试考点(题目),适用于19C/21C,跟着学OCP考试必过。 41. 第41题: 题目 解析及答案: 关于应用程序容器,以下哪三项是正确的? A) 它可以包含单个…...
走出 Demo,走向现实:DeepSeek-VL 的多模态工程路线图
目录 一、引言:多模态模型的关键转折点 (一)当前 LMM 的三个关键挑战 1. 数据的真实性不足 2. 模型设计缺乏场景感知 3. 语言能力与视觉能力难以兼顾 (二)DeepSeek-VL 的根本出发点:以真实任务为锚点…...
Kotlin 作用域函数全解析:let、run、with、apply、also 应该怎么选?
Kotlin 提供了一套优雅的“作用域函数”(Scope Functions),包括:let、run、with、apply 和 also。它们看起来相似,行为上也有交集,但却各有侧重。掌握它们的使用场景,不仅能让代码更简洁&#x…...
Python 矩阵运算:从理论到实践
Python 矩阵运算:从理论到实践 在数据分析、机器学习以及科学计算等诸多领域,矩阵运算均扮演着极为重要的角色。借助 Python 的 NumPy 库,我们可以便捷地实现各类矩阵运算。本文将深入探讨矩阵运算的数学原理,并通过实例演示如何…...
系统架构-层次式架构设计
层次式体系结构是最通用的架构,大部分的应用会分成表现层(展示层)、中间层(业务层)、数据访问层(持久层)和数据层 表现层架构设计 使用XML设计表现层 使用UIP框架设计表现层,UIP将…...
《Python星球日记》第29天:Flask进阶
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏:《Python星球日记》,限时特价订阅中ing 目录 一、重温 Flask 框架二、路由与视图1. 动态路由2. 路由装饰器三、模板渲染1. Jinja2 模板语法2.…...
Baklib知识中台:智能服务架构新实践
智能服务架构四库体系 Baklib 知识中台的核心竞争力源于其独创的四库体系架构设计。该体系通过知识资源库、业务场景库、智能模型库和服务规则库的有机联动,构建起覆盖知识全生命周期的管理闭环。其中,知识资源库依托自然语言处理技术实现多源异构数据的…...
CBAM透视镜:穿透软件架构成本迷雾的评估范式
文章目录 一、引言二、CBAM 基础理论2.1 CBAM 的定义与概念2.2 CBAM 的核心原理2.2.1 成本效益分析的基本逻辑2.2.2 定量化决策过程 2.3 CBAM 与其他软件架构评估方法的比较2.3.1 与 ATAM 对比2.3.2 与 SAAM 对比 三、CBAM 在软件架构中的应用流程3.1 确定评估目标3.2 列出架构…...
macbook install chromedriver
# 打开 Chrome 访问以下地址查看版本 chrome://version/# 终端查看版本号 (示例输出: 125.0.6422.113) /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version测试:...
Java 一战式学习指南,很详细
java基础 一、简介 1.1 JDK Java Develop Kit : Java的开发包,包含了Java的类库、执行Java所需的允许环境、各种开发辅助工具等... JDK 分为 Oracle JDK 和 Open JDK ,Oracle JDK需要商业许可证,是收费的。Open JDK 则是免费的。 1.2 Ja…...
从零开始开发纯血鸿蒙应用之NAPI
从零开始开发纯血鸿蒙应用 〇、前言一、解耦良器——Adapter二、详学 NAPI1、注册自定义的 NAPI1.1、Index.d.ts1.2、napi_property_descriptor 数组 2、读取参数2.1、读取字符类型数据2.1、读取数字类型 3、封装返回值4、C/C 调用 ArkTS 方法5、自定义 C 类的透传 三、总结坑点…...
立夏三候:蝼蝈鸣,蚯蚓出,王瓜生
今(5月5日)天是立夏节气,尽管本“人民+体验官”已是最畏惧感到气喘吁吁这夏天气候之老龄人,但还是要推广人民日报官方微博文化产品《文化中国行看立夏节气》。 人民微博着重提示“立夏三候”三个方面:“一候…...
Nuxt3还能用吗?
Nuxt3还能用吗? 前一段时间,我完成了整个产品,从Nuxt到Next的迁移,因为面临了一些在框架层面就无法解决的问题。 payload json化 在所有的的Nuxt中,我们都能看到有这样一个东西。 其实有这个东西也很正常࿰…...
专业课复习笔记 4
前言 实际上对于我的考研来说,最重要的两门就是数学和专业课。所以从今天开始,我尽可能多花时间学习数学和专业课。把里面的知识和逻辑关系理解清楚,把常考的内容练习透彻。就这样。 寻址方式 立即数寻址 操作数在指令里面直接提供了。 …...
[人机交互]交互设计
零.本章的主要目标 本章主要目标总结 区分良与非良交互设计,突出产品可用性差异阐述交互设计与HCI及其他领域的关系解释可用性概念概述交互设计过程涉及的内容概述交互设计中所使用的指南形式从可用性目标和原理角度,评估并解释产品的成败 一.什么是交…...
LeetCode 热题 100 17. 电话号码的字母组合
LeetCode 热题 100 | 17. 电话号码的字母组合 大家好,今天我们来解决一道经典的算法题——电话号码的字母组合。这道题在 LeetCode 上被标记为中等难度,要求给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。下面我将详细讲解解…...
【从零开始学习微服务 | 第一篇】单体项目到微服务拆分实践
目录 引言 一、选择聚合结构进行拆分的优势 二、微服务模块创建步骤 (一)引入 pom 文件与修改 (二)创建 Spring Boot 启动类 (三)搭建基本包结构 三、配置文件的引入与调整 四、业务代码的引入与注意…...
微前端qiankun动态路由权限设计与数据通信方案
思路: 权限控制中心化:主应用负责统一的管理权限,子路由上报路由信息 动态路由加载:根据用户权限动态注册可用路由 数据通信机制 主应用和子应用:通过qiankun提供的props和全局状态 子应用和子应用:通过…...
VTK 数据读取/写入类介绍
概述 VTK提供了多种数据读取和写入类,支持各种格式的输入输出操作,包括图像数据、多边形数据、结构化/非结构化网格数据等。 常用VTK读取类 vtkSTLReader 读取STL格式文件 属性: FileName - 要读取的STL文件名 方法: SetFileName(const char*) - 设置文件名 GetFileName…...
41.寻找缺失的第一个正数:原地哈希算法详解
文章目录 引言问题描述方法思路:原地哈希算法算法步骤 完整代码实现关键代码解析复杂度分析示例说明总结 引言 在算法面试和数据处理中,寻找缺失的第一个正数是一个经典问题。题目要求给定一个未排序的整数数组,找到其中缺失的最小正整数&am…...
项目实战-基于信号处理与SVM机器学习的声音情感识别系统
目录 一.背景描述 二.理论部分 三.程序设计 编程思路 流程图 1.信号部分 创建数据 generate_samples.py 头文件 生成函数 generate_emotion_sample 传入参数 存储路径 生成参数 创建基础正弦波信号 调制基础正弦波 对于愤怒可以增加噪声 归一化信号 存储 主函…...
基于Docker的MongoDB环境搭建:从零开始的完整实践指南
在现代应用开发中,容器化技术已成为构建可移植、易维护的服务环境的标准方案。MongoDB作为NoSQL数据库的代表,与Docker结合后能够显著提升部署效率。本文将深入解析如何通过Docker搭建安全可靠的MongoDB环境,涵盖基础配置、数据持久化、权限管理及安全加固等核心环节。 一、…...
C++ 类与对象(下)—— 进阶特性与底层机制解析(构造函数初始化,类型转换,static成员,友元,内部类,匿名对象)
一、构造函数初始化列表:给成员变量 “精准出生证明” 在 C 中,构造函数对成员变量的初始化方式有 初始化列表 和 函数体内赋值 两种。初始化列表是构造函数的一个重要特性,它允许在对象创建时对成员变量进行初始化。与在构造函数体内赋值不同…...
项目生成日志链路id,traceId
Trace 1. 注册filter package com.sc.account.config;import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public cla…...
SQL常见误区
查询的顺序 书写顺序 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表。。他们的加载顺序 逻辑处理实际顺序 常见错误 在 WHERE 中使用 SELECT 的别名 sql – 错误示例(WHERE 中不能使用别名…...
android zxing QrCode 库集成转竖屏适配问题
由于zxing 这个库使用比较广泛,所以大家也都遇到这个问题了,甚至最早可以追溯到十年前甚至更早,所以原创是谁已经无法找到,表明转载又需要填原文链接,就腆着脸标个原创了,不过的确不是我的原创,…...
实验4 mySQL查询和视图
一、实验目的 掌握SELECT语句的基本语法多表连接查询GROUP BY的使用方法。ORDER BY的使用方法。 二、实验步骤、内容、结果 实验内容: 实验4.1数据库的查询 目的与要求 (1)掌握SELECT语句的基本语法。 (2)掌握子查询的表示。 (3)掌握连接查询的表示。 (4)掌…...
解决用Deveco device tool无法连接local pc
原文链接:https://kashima19960.github.io/2025/05/05/openharmony/解决用Deveco%20device%20tool无法连接local%20pc/ 问题描述 WindowsUbuntu 环境下DevEco tool upload Hi3681开发 烧录 Local PC 箭头红一下,又绿了 用Deveco device tool进行upload…...
Google-chrome版本升级后sogou输入法不工作了
背景: 笔记本Thinkpad E450,操作系统Ubuntu 24.04.2 LTS,Chrome浏览器版本135.0.7049.114-1,Edge浏览器版本131.0.2903.99-1,输入法Sogou版本4.2.1.145 现象: - **正常场景**:Edge中可通过Ctrl…...