第22篇:Python开发进阶:详解使用SQLAlchemy进行ORM数据库编程技术

news2025/1/27 7:42:41

第22篇:使用SQLAlchemy进行ORM

内容简介

在现代应用开发中,对象关系映射(ORM,Object-Relational Mapping)是一种将对象编程语言中的对象与关系型数据库中的数据进行映射的技术。SQLAlchemy是Python中功能强大且灵活的ORM框架,广泛用于简化数据库操作。本文将深入探讨ORM的概念,介绍SQLAlchemy的安装与配置,指导如何定义模型,执行CRUD操作,并详细讲解如何在模型之间定义关系。通过理论与实践相结合的方式,您将全面掌握使用SQLAlchemy进行数据库操作的技能。


目录

  1. ORM概述
    • 什么是ORM?
    • ORM的优势
    • 常见的Python ORM框架
  2. SQLAlchemy的安装与配置
    • 安装SQLAlchemy
    • 安装数据库驱动
    • 创建数据库引擎
  3. 定义模型
    • 创建基类
    • 定义模型类
    • 创建数据库表
  4. 执行CRUD操作
    • 创建记录(Create)
    • 读取记录(Read)
    • 更新记录(Update)
    • 删除记录(Delete)
  5. 关系定义
    • 一对多关系
    • 多对多关系
    • 一对一关系
  6. 实践项目:使用SQLAlchemy构建博客系统
    • 项目概述
    • 步骤一:设置数据库
    • 步骤二:定义模型
    • 步骤三:执行CRUD操作
    • 步骤四:定义模型关系
  7. 常见问题及解决方法
    • 问题1:如何处理数据库迁移?
    • 问题2:如何优化查询性能?
    • 问题3:如何处理复杂关系?
  8. 总结

ORM概述

什么是ORM?

**对象关系映射(ORM,Object-Relational Mapping)**是一种编程技术,旨在将面向对象编程语言中的对象与关系型数据库中的数据表进行映射。通过ORM,开发者可以使用面向对象的方式操作数据库,而无需编写大量的SQL语句。

示例

假设有一个User类和一个users表,ORM允许我们通过操作User对象来增删改查users表中的数据。

ORM的优势

  • 简化代码:减少手写SQL语句,使用面向对象的方式操作数据。
  • 提高生产力:快速开发和迭代,专注于业务逻辑。
  • 数据库无关性:通过配置不同的数据库驱动,轻松切换数据库。
  • 安全性:自动处理参数化查询,防止SQL注入攻击。
  • 维护性:集中管理模型类,代码结构清晰,便于维护和扩展。

常见的Python ORM框架

  • SQLAlchemy:功能强大且灵活,支持多种数据库,适用于复杂项目。
  • Django ORM:集成在Django框架中,适用于快速开发Web应用。
  • Peewee:轻量级ORM,适用于小型项目或嵌入式数据库。
  • Tortoise ORM:支持异步操作,适用于异步Web框架如FastAPI。

SQLAlchemy的安装与配置

安装SQLAlchemy

使用pip安装最新版本的SQLAlchemy:

pip install SQLAlchemy

安装数据库驱动

根据所使用的数据库,安装相应的数据库驱动。例如:

  • MySQLmysql-connector-pythonPyMySQL

    pip install mysql-connector-python
    # 或
    pip install PyMySQL
    
  • PostgreSQLpsycopg2

    pip install psycopg2
    
  • SQLite:无需额外安装,Python标准库已内置支持。

创建数据库引擎

数据库引擎是SQLAlchemy与数据库进行通信的接口。通过create_engine函数创建引擎对象。

示例代码

from sqlalchemy import create_engine

# MySQL连接字符串格式:mysql+mysqlconnector://username:password@host:port/database
DATABASE_URL = "mysql+mysqlconnector://root:your_password@localhost:3306/online_store"

# 创建引擎
engine = create_engine(DATABASE_URL, echo=True)

说明

  • echo=True:启用SQLAlchemy的日志记录,显示生成的SQL语句,便于调试。
  • 替换usernamepasswordhostportdatabase为实际的数据库配置。

定义模型

创建基类

使用declarative_base创建基类,所有的模型类都将继承自该基类。

示例代码

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

定义模型类

通过继承基类,定义与数据库表对应的模型类。每个模型类的属性对应数据库表的列。

示例代码

from sqlalchemy import Column, Integer, String, Float, Text, TIMESTAMP, func

class Product(Base):
    __tablename__ = 'products'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(100), nullable=False)
    description = Column(Text)
    price = Column(Float, nullable=False)
    stock = Column(Integer, default=0)
    created_at = Column(TIMESTAMP, server_default=func.now())

    def __repr__(self):
        return f"<Product(name='{self.name}', price={self.price}, stock={self.stock})>"

说明

  • __tablename__:指定数据库表名。
  • Column:定义表的列及其属性,如数据类型、主键、默认值等。
  • __repr__:定义对象的字符串表示,便于调试和日志记录。

创建数据库表

使用Base.metadata.create_all根据模型定义创建数据库表。

示例代码

# 创建所有表
Base.metadata.create_all(engine)

说明

  • 确保在定义所有模型类后调用此方法,以创建相应的数据库表。
  • 如果表已存在,create_all不会重复创建。

执行CRUD操作

创建记录(Create)

通过会话对象添加新记录并提交到数据库。

示例代码

from sqlalchemy.orm import sessionmaker

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

# 创建新产品
new_product = Product(name='无线鼠标', description='高精度无线鼠标,舒适手感。', price=49.99, stock=150)
session.add(new_product)
session.commit()

print("新产品已添加:", new_product)

说明

  • sessionmaker:创建会话工厂,绑定到引擎。
  • session.add:将新对象添加到会话。
  • session.commit:提交事务,将更改保存到数据库。

读取记录(Read)

通过会话对象查询数据库中的记录。

示例代码

# 查询所有产品
products = session.query(Product).all()
for product in products:
    print(product)

# 根据条件查询
expensive_products = session.query(Product).filter(Product.price > 100).all()
for product in expensive_products:
    print(product)

说明

  • session.query(Model).all():获取表中的所有记录。
  • filter:添加查询条件。

更新记录(Update)

修改已有记录并提交更改。

示例代码

# 查询要更新的产品
product_to_update = session.query(Product).filter_by(name='无线鼠标').first()
if product_to_update:
    product_to_update.price = 44.99  # 更新价格
    product_to_update.stock += 50      # 增加库存
    session.commit()
    print(f"更新后的产品: {product_to_update}")
else:
    print("未找到指定的产品")

说明

  • 通过查询获取要更新的对象,直接修改对象属性后提交事务。

删除记录(Delete)

删除指定记录并提交更改。

示例代码

# 查询要删除的产品
product_to_delete = session.query(Product).filter_by(name='无线鼠标').first()
if product_to_delete:
    session.delete(product_to_delete)
    session.commit()
    print("产品已删除")
else:
    print("未找到指定的产品")

说明

  • 使用session.delete删除对象,然后提交事务。

关系定义

在实际应用中,数据库表之间通常存在各种关系。SQLAlchemy支持定义和管理这些关系。

一对多关系

示例场景:一个Category(类别)有多个Product(产品)。

模型定义

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

class Category(Base):
    __tablename__ = 'categories'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50), nullable=False, unique=True)
    products = relationship('Product', back_populates='category')

    def __repr__(self):
        return f"<Category(name='{self.name}')>"

class Product(Base):
    __tablename__ = 'products'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(100), nullable=False)
    description = Column(Text)
    price = Column(Float, nullable=False)
    stock = Column(Integer, default=0)
    category_id = Column(Integer, ForeignKey('categories.id'))
    created_at = Column(TIMESTAMP, server_default=func.now())

    category = relationship('Category', back_populates='products')

    def __repr__(self):
        return f"<Product(name='{self.name}', price={self.price}, stock={self.stock})>"

说明

  • ForeignKey:在Product模型中添加category_id列,作为外键引用categories.id
  • relationship:在CategoryProduct模型中定义关系,back_populates用于双向关联。

使用示例

# 创建新类别
new_category = Category(name='电子产品')
session.add(new_category)
session.commit()

# 创建新产品并关联类别
new_product = Product(name='智能手表', description='功能丰富的智能手表。', price=199.99, stock=80, category=new_category)
session.add(new_product)
session.commit()

# 查询类别及其产品
category = session.query(Category).filter_by(name='电子产品').first()
print(category)
for product in category.products:
    print(product)

多对多关系

示例场景:一个Student(学生)可以选修多个Course(课程),一个Course可以被多个Student选修。

模型定义

from sqlalchemy import Table

# 关联表
student_course = Table('student_course', Base.metadata,
    Column('student_id', Integer, ForeignKey('students.id')),
    Column('course_id', Integer, ForeignKey('courses.id'))
)

class Student(Base):
    __tablename__ = 'students'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(100), nullable=False)
    courses = relationship('Course', secondary=student_course, back_populates='students')

    def __repr__(self):
        return f"<Student(name='{self.name}')>"

class Course(Base):
    __tablename__ = 'courses'

    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(100), nullable=False)
    students = relationship('Student', secondary=student_course, back_populates='courses')

    def __repr__(self):
        return f"<Course(title='{self.title}')>"

说明

  • 使用Table定义关联表student_course,不需要单独的模型类。
  • StudentCourse模型中通过relationship定义多对多关系,secondary参数指定关联表。

使用示例

# 创建新学生和课程
student = Student(name='张三')
course1 = Course(title='Python编程')
course2 = Course(title='数据库管理')
session.add_all([student, course1, course2])
session.commit()

# 关联学生与课程
student.courses.append(course1)
student.courses.append(course2)
session.commit()

# 查询学生及其选修的课程
student = session.query(Student).filter_by(name='张三').first()
print(student)
for course in student.courses:
    print(course)

# 查询课程及其选修的学生
course = session.query(Course).filter_by(title='Python编程').first()
print(course)
for student in course.students:
    print(student)

一对一关系

示例场景:每个User(用户)有一个唯一的Profile(个人资料)。

模型定义

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True, autoincrement=True)
    username = Column(String(50), nullable=False, unique=True)
    profile = relationship('Profile', uselist=False, back_populates='user')

    def __repr__(self):
        return f"<User(username='{self.username}')>"

class Profile(Base):
    __tablename__ = 'profiles'

    id = Column(Integer, primary_key=True, autoincrement=True)
    bio = Column(Text)
    user_id = Column(Integer, ForeignKey('users.id'))
    user = relationship('User', back_populates='profile')

    def __repr__(self):
        return f"<Profile(bio='{self.bio}')>"

说明

  • User模型中,profile关系使用uselist=False表示一对一关系。
  • Profile模型通过user_id外键关联User模型。

使用示例

# 创建新用户和个人资料
user = User(username='alice')
profile = Profile(bio='数据科学爱好者', user=user)
session.add(user)
session.add(profile)
session.commit()

# 查询用户及其个人资料
user = session.query(User).filter_by(username='alice').first()
print(user)
print(user.profile)

# 查询个人资料及其用户
profile = session.query(Profile).filter_by(bio='数据科学爱好者').first()
print(profile)
print(profile.user)

实践项目:使用SQLAlchemy构建博客系统

项目概述

本项目将通过构建一个简单的博客系统,展示如何使用SQLAlchemy进行数据库操作。博客系统包括User(用户)、Post(帖子)和Comment(评论)三个模型,展示一对多和多对一的关系。

步骤一:设置数据库

假设使用MySQL数据库,已创建名为blog的数据库,并安装了mysql-connector-python驱动。

数据库引擎创建

from sqlalchemy import create_engine

DATABASE_URL = "mysql+mysqlconnector://root:your_password@localhost:3306/blog"
engine = create_engine(DATABASE_URL, echo=True)

步骤二:定义模型

模型定义

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Text, ForeignKey, TIMESTAMP, func
from sqlalchemy.orm import relationship

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True, autoincrement=True)
    username = Column(String(50), nullable=False, unique=True)
    email = Column(String(100), nullable=False, unique=True)
    posts = relationship('Post', back_populates='author')
    comments = relationship('Comment', back_populates='author')

    def __repr__(self):
        return f"<User(username='{self.username}', email='{self.email}')>"

class Post(Base):
    __tablename__ = 'posts'

    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(200), nullable=False)
    content = Column(Text, nullable=False)
    created_at = Column(TIMESTAMP, server_default=func.now())
    author_id = Column(Integer, ForeignKey('users.id'))
    author = relationship('User', back_populates='posts')
    comments = relationship('Comment', back_populates='post')

    def __repr__(self):
        return f"<Post(title='{self.title}', author='{self.author.username}')>"

class Comment(Base):
    __tablename__ = 'comments'

    id = Column(Integer, primary_key=True, autoincrement=True)
    content = Column(Text, nullable=False)
    created_at = Column(TIMESTAMP, server_default=func.now())
    author_id = Column(Integer, ForeignKey('users.id'))
    post_id = Column(Integer, ForeignKey('posts.id'))
    author = relationship('User', back_populates='comments')
    post = relationship('Post', back_populates='comments')

    def __repr__(self):
        return f"<Comment(author='{self.author.username}', post='{self.post.title}')>"

创建表

# 创建所有表
Base.metadata.create_all(engine)

步骤三:执行CRUD操作

创建用户、帖子和评论

from sqlalchemy.orm import sessionmaker

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

# 创建新用户
user1 = User(username='john_doe', email='john@example.com')
session.add(user1)
session.commit()

# 创建新帖子
post1 = Post(title='我的第一篇博客', content='这是我的第一篇博客内容。', author=user1)
session.add(post1)
session.commit()

# 创建评论
comment1 = Comment(content='很棒的文章!', author=user1, post=post1)
session.add(comment1)
session.commit()

print("用户、帖子和评论已创建")

读取帖子及其评论

# 查询帖子
post = session.query(Post).filter_by(title='我的第一篇博客').first()
print(post)
for comment in post.comments:
    print(comment)

更新帖子内容

# 更新帖子内容
post = session.query(Post).filter_by(title='我的第一篇博客').first()
if post:
    post.content = '这是更新后的博客内容。'
    session.commit()
    print("帖子内容已更新")

删除评论

# 删除评论
comment = session.query(Comment).filter_by(content='很棒的文章!').first()
if comment:
    session.delete(comment)
    session.commit()
    print("评论已删除")

步骤四:定义模型关系

在上述模型定义中,已经展示了一对多和多对一的关系。以下进一步介绍如何使用back_populatescascade参数管理关系。

示例代码

# 删除用户时,级联删除其所有帖子和评论
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True, autoincrement=True)
    username = Column(String(50), nullable=False, unique=True)
    email = Column(String(100), nullable=False, unique=True)
    posts = relationship('Post', back_populates='author', cascade='all, delete-orphan')
    comments = relationship('Comment', back_populates='author', cascade='all, delete-orphan')

    # 其他部分保持不变

# 删除用户
user = session.query(User).filter_by(username='john_doe').first()
if user:
    session.delete(user)
    session.commit()
    print("用户及其相关帖子和评论已删除")

说明

  • cascade='all, delete-orphan':当删除User对象时,自动删除与之关联的PostComment对象,防止孤立数据。

常见问题及解决方法

问题1:如何处理数据库迁移?

原因:随着项目的发展,数据库的结构可能需要修改,如添加新表、修改列等。手动管理数据库迁移容易出错,需使用迁移工具。

解决方法

  • Alembic:SQLAlchemy官方的数据库迁移工具,支持版本控制和自动生成迁移脚本。

安装Alembic

pip install alembic

使用示例

  1. 初始化Alembic

    alembic init alembic
    
  2. 配置alembic.ini:设置数据库连接字符串。

  3. 编辑env.py:导入模型的元数据。

    from your_model_module import Base
    target_metadata = Base.metadata
    
  4. 生成迁移脚本

    alembic revision --autogenerate -m "Initial migration"
    
  5. 应用迁移

    alembic upgrade head
    

说明

  • 版本控制:Alembic跟踪数据库结构的变化,支持回滚和升级。
  • 自动生成:根据模型定义自动生成迁移脚本,减少手动操作。

问题2:如何优化查询性能?

原因:随着数据量的增加,未优化的查询可能导致性能下降。

解决方法

  1. 使用索引

    为常用的查询字段创建索引,加速数据检索。

    示例

    from sqlalchemy import Index
    
    class Product(Base):
        __tablename__ = 'products'
        # 列定义保持不变
    
    Index('idx_product_price', Product.price)
    
  2. 懒加载与预加载

    使用lazy参数控制关联对象的加载方式,避免不必要的数据库查询。

    示例

    class Post(Base):
        __tablename__ = 'posts'
        # 列定义保持不变
        comments = relationship('Comment', back_populates='post', lazy='joined')
    
  3. 分页查询

    对大量数据进行分页,减少一次性返回的数据量。

    示例

    page = 2
    per_page = 10
    posts = session.query(Post).offset((page - 1) * per_page).limit(per_page).all()
    for post in posts:
        print(post)
    
  4. 优化查询语句

    避免不必要的JOIN和子查询,使用高效的过滤条件。

问题3:如何处理复杂关系?

原因:在复杂应用中,模型之间可能存在多种关系,如多对多、自关联等。

解决方法

  1. 多对多关系

    通过关联表管理多对多关系,如StudentCourse

  2. 自关联关系

    模型与自身建立关系,如EmployeeManager

    示例代码

    class Employee(Base):
        __tablename__ = 'employees'
    
        id = Column(Integer, primary_key=True, autoincrement=True)
        name = Column(String(100), nullable=False)
        manager_id = Column(Integer, ForeignKey('employees.id'))
        subordinates = relationship('Employee', backref='manager', remote_side=[id])
    
        def __repr__(self):
            return f"<Employee(name='{self.name}', manager='{self.manager.name if self.manager else None}')>"
    

说明

  • remote_side:指定关联的远端列,避免递归引用问题。
  • backref:为反向关系创建别名,方便访问。

总结

在本篇文章中,我们深入探讨了ORM(对象关系映射)的概念,介绍了SQLAlchemy的安装与配置,详细讲解了如何定义模型,执行CRUD操作,并展示了如何在模型之间定义各种关系。通过构建实际的博客系统项目,您不仅掌握了SQLAlchemy的基本用法,还了解了如何处理复杂的数据库关系和优化查询性能。

学习建议

  1. 深入学习SQLAlchemy文档:了解更多高级功能,如事件系统、扩展库等,提升使用能力。
  2. 实践项目:通过构建实际项目,如电商平台、社交网络等,应用所学知识,积累实战经验。
  3. 学习数据库设计:掌握数据库规范化、索引优化和性能调优,提升数据库管理能力。
  4. 探索异步ORM:了解支持异步操作的ORM框架,如Tortoise ORM,适应现代异步Web框架的需求。
  5. 参与开源项目:通过贡献开源项目,学习业界最佳实践,扩展技术视野。

如果您有任何问题或需要进一步的帮助,请随时在评论区留言或联系相关技术社区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2283304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW 太阳能光伏发电系统智能监控

本文介绍了基于 LabVIEW 的太阳能光伏发电监控系统的设计与实现&#xff0c;着重探讨了其硬件配置、软件架构以及系统的实现方法。该系统能够有效提高太阳能光伏发电的监控效率和精确性&#xff0c;实现了远程监控和数据管理的智能化。 ​ 项目背景 在当前能源紧张与环境污染…

记录让cursor帮我给ruoyi-vue后台管理项目整合mybatis-plus

自己整合过程中会出现 work.web.exception.GlobalExceptionHandler :100 | 请求地址/admin/device/install/detail/1,发生未知异常. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.fire.mapper.DeviceInstallMapper.selectById at o…

Prometheus+grafana实践:Doris数据库的监控

文章来源&#xff1a;乐维社区 Doris数据库背景 Doris&#xff08;Apache Doris&#xff09;是一个现代化的MPP&#xff08;Massive Parallel Processing&#xff0c;大规模并行处理&#xff09;数据库&#xff0c;主要用于在线分析处理&#xff08;OLAP&#xff09;场景。 D…

CYT3BB_4BB:Clock system

CYT3BB/4BB的时钟系统包括8-MHz IMO、2个ILO、4个看门狗计时器、4个PLL、一个FLL、5个时钟监控器(CSV)、一个8-33.34MHzECO和一个32.768-kHz WCO。   该时钟系统支持三个主时钟域: CLK_HF、CLK_SLOW和CLK_LF。 - CLK_HFx: CLK_HFx是活动模式的时钟。每个人都可以使用任…

神经网络|(四)概率论基础知识-古典概型

【1】引言 前序学习了线性回归的基础知识&#xff0c;了解到最小二乘法可以做线性回归分析&#xff0c;但为何最小二乘法如此准确&#xff0c;这需要从概率论的角度给出依据。 因此从本文起&#xff0c;需要花一段时间来回顾概率论的基础知识。 【2】古典概型 古典概型是我…

OpenFGA

1.什么是OpenFGA Fine-Grained Authorization 细粒度关系型授权 2.什么是细粒度授权 细粒度授权 (FGA) 意味着能够授予特定用户在特定资源中执行特定操作的权限。 精心设计的 FGA 系统允许您管理数百万个对象和用户的权限。随着系统不断添加对象并更新用户的访问权限&#…

C语言程序设计:算法程序的灵魂

文章目录 C语言程序设计&#xff1a;算法程序的灵魂算法数据结构程序数据结构算法数值运算算法非数值运算算法 简单的算法举例【例2.1】求12345【例2.2】有50个学生&#xff0c;要求输出成绩在80分以上的学生的学号和成绩 简单的算法举例【例2.3】判定2000—2500年中的每一年是…

React和Vue有什么区别,如何选择?

React和Vue有什么区别&#xff0c;如何选择&#xff1f; React 和 Vue 是当前最受欢迎的前端框架之一&#xff0c;两者在开发者中都有极高的声誉。它们都旨在帮助开发人员构建用户界面&#xff0c;但在实现方式和适用场景上有所不同。如果你正考虑在项目中选择 React 或 Vue&a…

寒假1.23

题解 web&#xff1a;[极客大挑战 2019]Secret File&#xff08;文件包含漏洞&#xff09; 打开链接是一个普通的文字界面 查看一下源代码 发现一个链接&#xff0c;点进去看看 再点一次看看&#xff0c;没什么用 仔细看&#xff0c;有一个问题&#xff0c;当点击./action.ph…

从spec到iso的koji使用

了解一下Linux发行版流程&#xff1a;:从spec到iso的koji使用 for Fedora 41。 Fedora 41有24235个包&#xff0c;我们选择 minimal 的几十个源码包&#xff0c;百多个rpm包构建。 配3台服务器 40C64G 48C64G 80C128G&#xff0c;有点大材小用&#xff0c;一台就够了 &#xf…

【游戏设计原理】81 - 功能可见性暗示

一、什么是功能可见性&#xff1f; 功能可见性&#xff08;Affordance&#xff09;是一个设计心理学的概念&#xff0c;指的是物体或界面元素通过其外观或形态向用户传递的功能暗示。换句话说&#xff0c;功能可见性是指一个物体本身所具备的特性&#xff0c;使人能直接感知到…

mathematical-expression 实现 数学表达式解析 Java 篇(最新版本)

mathematical-expression &#xff08;MAE&#xff09; 切换至 中文文档 Community QQ group 访问链接进行交流信息的获取&#xff1a;https://diskmirror.lingyuzhao.top/DiskMirrorBackEnd/FsCrud/downLoad/18/Binary?fileNameArticle/Image/-56202138/1734319937274.jpg…

MVCC底层原理实现

MVCC的实现原理 了解实现原理之前&#xff0c;先理解下面几个组件的内容 1、 当前读和快照读 先普及一下什么是当前读和快照读。 当前读&#xff1a;读取数据的最新版本&#xff0c;并对数据进行加锁。 例如&#xff1a;insert、update、delete、select for update、 sele…

WPF实战案例 | C# WPF实现计算器源码

WPF实战案例 | C# WPF实现计算器源码 一、设计来源计算器应用程序讲解1.1 主界面1.2 计算界面 二、效果和源码2.1 界面设计&#xff08;XAML&#xff09;2.2 代码逻辑&#xff08;C#&#xff09;2.3 实现步骤总结 源码下载更多优质源码分享 作者&#xff1a;xcLeigh 文章地址&a…

vulnhub靶场【kioptrix-3】靶机

前言 靶机&#xff1a;kioptrix-3&#xff0c;IP地址为192.168.1.74 攻击&#xff1a;kali&#xff0c;IP地址为192.168.1.16 都采用虚拟机&#xff0c;网卡为桥接模式 文章中涉及的靶机&#xff0c;来源于vulnhub官网&#xff0c;想要下载&#xff0c;可自行访问官网下载&a…

无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整

无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整 0 前言 之前文章添加了一个自定义的模块&#xff0c;本篇文章在之前的自定义模块中&#xff0c;添加两个自定义参数 使用QGC显示出来&#xff0c;并通过QGC调整参数值&#xff0c;代码实现参数更新 新增的参…

【Linux】华为服务器使用U盘安装统信操作系统

目录 一、准备工作 1.1 下载UOS官方系统 &#xff11;.&#xff12;制作启动U盘 1.3 服务器智能管理系统iBMC 二、iBMC设置U盘启动 一、准备工作 1.1 下载UOS官方系统 服务器CPU的架构是x86-64还是aarch64&#xff09;,地址&#xff1a;统信UOS生态社区 - 打造操作系统创…

npm常见报错整理

npm install时报UNMET PEER DEPENDENCY 现象 npm install时报UNMET PEER DEPENDENCY,且执行npm install好几遍仍报这个。 原因 不是真的缺少某个包,而是安装的依赖版本不对,警告你应该安装某一个版本。 真的缺少某个包。 解决 看了下package.json文件,我的react是有的…

在宝塔安装部署mindoc

MinDoc简介 MinDoc 是一款针对IT团队开发的简单好用的文档管理系统。 MinDoc 的前身是 SmartWiki 文档系统。SmartWiki 是基于 PHP 框架 laravel 开发的一款文档管理系统。因 PHP 的部署对普通用户来说太复杂&#xff0c;所以改用 Golang 开发。可以方便用户部署和实用。 开…

蓝桥杯练习日常|递归-进制转换

蓝桥云课760数的计算 一、递归 题目&#xff1a; 我的解题代码&#xff1a; #include <iostream> using namespace std; int sum0; int main() {// 请在此输入您的代码int n;cin>>n;int fun(int n);fun(n); cout<<sum<<\n;return 0; } // void fu…