news 2026/2/28 8:46:02

手把手搞定SQLAlchemy ORM:从模型定义到MySQL实战映射

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手搞定SQLAlchemy ORM:从模型定义到MySQL实战映射

手把手搞定SQLAlchemy ORM:从模型定义到MySQL实战映射

文章目录

    • 手把手搞定SQLAlchemy ORM:从模型定义到MySQL实战映射
      • 引言:为什么我们需要ORM?
      • 一、环境准备:搭建你的第一个ORM项目
        • 1.1 安装必要的包
        • 1.2 创建项目结构
        • 1.3 配置数据库连接
      • 二、核心概念:理解ORM的"映射"原理
        • 2.1 什么是"映射"?
        • 2.2 SQLAlchemy的两层架构
        • 2.3 声明式基类(Declarative Base)
      • 三、实战演练:创建你的第一个模型
        • 3.1 基础模型定义
        • 3.2 字段类型详解
        • 3.3 字段参数详解
      • 四、创建数据库表
        • 4.1 创建表的完整流程
        • 4.2 表创建的背后原理
      • 五、基本CRUD操作
        • 5.1 添加数据(Create)
        • 5.2 查询数据(Read)
        • 5.3 更新和删除(Update & Delete)
      • 六、高级特性:关系映射
        • 6.1 一对多关系
        • 6.2 关系查询
      • 七、实际项目应用建议
        • 7.1 项目结构优化
        • 7.2 性能优化技巧
        • 7.3 常见错误与解决方案
      • 八、学习总结与进阶
        • 8.1 核心要点
        • 8.2 下一步学习方向
      • 学习交流与互动

刚开始用Python操作MySQL时,你是不是也这样:写SQL语句写到手酸,字段名拼错一个字母调试半天,数据库表结构改了代码要跟着改一堆?我当时接手一个用户管理系统,光是用户表的CRUD就写了上百行重复代码,直到我发现了SQLAlchemy ORM这个“神器”。

引言:为什么我们需要ORM?

想象一下这个场景:你的Python项目要管理一个电商平台的用户数据。没有ORM时,每次查询用户都要写这样的代码:

importpymysql# 连接数据库(每次都要写)conn=pymysql.connect(host='localhost',user='root',password='123456',database='shop')cursor=conn.cursor()# 查询用户(SQL字符串容易拼错)sql="SELECT id, username, email, created_at FROM users WHERE id =%s"cursor.execute(sql,(1,))result=cursor.fetchone()# 手动处理结果(字段顺序要对齐)user={'id':result[0],'username':result[1],'email':result[2],'created_at':result[3]}# 别忘了关闭连接!cursor.close()conn.close()

痛点很明显

  1. SQL字符串硬编码,容易出错
  2. 结果集要手动转成字典或对象
  3. 连接管理繁琐,容易忘记关闭
  4. 表结构改了,所有相关代码都要改

ORM(对象关系映射)就是来解决这些问题的。它让数据库表变成Python类,记录变成对象,SQL操作变成方法调用。今天我们就用30分钟,彻底掌握SQLAlchemy ORM的核心——模型定义与映射。

一、环境准备:搭建你的第一个ORM项目

1.1 安装必要的包

打开终端,执行以下命令:

# 安装SQLAlchemy核心库pipinstallsqlalchemy# 安装MySQL驱动(推荐pymysql)pipinstallpymysql# 可选:安装日期时间处理库pipinstallpython-dateutil

为什么选择pymysql而不是mysql-connector?
我刚开始也纠结过,后来发现pymysql对Python3支持更好,而且是纯Python实现,安装简单。mysql-connector虽然是官方驱动,但在某些Linux环境下配置比较麻烦。

1.2 创建项目结构

my_orm_project/ ├── models/ # 存放所有模型类 │ ├── __init__.py │ └── user.py # 用户模型 ├── config.py # 数据库配置 ├── main.py # 主程序 └── requirements.txt

1.3 配置数据库连接

config.py中:

# config.py - 数据库配置importosfromsqlalchemyimportcreate_enginefromsqlalchemy.ormimportsessionmakerclassDatabaseConfig:"""数据库配置类"""# MySQL连接信息 - 改成你自己的DB_HOST='localhost'DB_PORT=3306DB_USER='root'DB_PASSWORD='your_password'DB_NAME='orm_demo'# 构建连接字符串# 格式:mysql+pymysql://用户名:密码@主机:端口/数据库名DATABASE_URL=f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"# 创建数据库引擎# echo=True会在控制台输出SQL语句,调试时非常有用engine=create_engine(DATABASE_URL,echo=True)# 创建Session工厂# Session相当于数据库连接的"会话",管理事务和连接SessionLocal=sessionmaker(autocommit=False,autoflush=False,bind=engine)@staticmethoddefget_db():"""获取数据库会话(依赖注入用)"""db=DatabaseConfig.SessionLocal()try:yielddbfinally:db.close()# 测试连接if__name__=="__main__":try:conn=DatabaseConfig.engine.connect()print("✅ 数据库连接成功!")conn.close()exceptExceptionase:print(f"❌ 连接失败:{e}")

运行这个文件,确保连接成功。如果失败,检查MySQL服务是否启动,用户名密码是否正确。

二、核心概念:理解ORM的"映射"原理

在深入代码之前,我们先搞清楚几个关键概念。很多新手直接跳进写代码,结果遇到问题不知道怎么回事。

2.1 什么是"映射"?

你可以把映射理解为翻译官

  • 数据库表 → Python类
  • 表字段 → 类属性
  • 表记录 → 类实例
  • SQL操作 → 类方法
classDiagram direction LR class 数据库表 { +表名: users +字段: id, name, email +记录: {id:1, name:"张三"} } class Python类 { +类名: User +属性: id, name, email +实例: user = User(name="张三") } 数据库表 --> Python类 : ORM映射 数据库表: 记录 --> Python类: 实例 : 对象化

2.2 SQLAlchemy的两层架构

SQLAlchemy分为两个主要部分:

  1. Core(核心层):处理SQL表达式、连接池、事务等底层操作
  2. ORM(对象关系映射层):在Core之上,提供面向对象的接口

为什么这样设计?
我刚开始觉得这很复杂,后来发现这样设计很聪明。如果你只需要执行原始SQL,用Core就行;如果需要对象化操作,就用ORM。两者可以混合使用!

2.3 声明式基类(Declarative Base)

这是SQLAlchemy ORM的起点。所有模型类都继承自这个基类:

fromsqlalchemy.ext.declarativeimportdeclarative_base# 创建声明式基类Base=declarative_base()

这个Base类会跟踪所有继承它的类,并自动创建对应的数据库表。你可以把它看作模型注册中心

三、实战演练:创建你的第一个模型

现在我们来创建电商系统中最常见的用户模型。

3.1 基础模型定义

models/user.py中:

# models/user.py - 用户模型fromsqlalchemyimportColumn,Integer,String,DateTime,Textfromsqlalchemy.sqlimportfuncfromdatetimeimportdatetimeimportconfig# 从config导入Base(需要在config.py中定义)# 我们先在本地创建,后面再整合fromsqlalchemy.ext.declarativeimportdeclarative_baseBase=declarative_base()classUser(Base):"""用户模型类对应数据库中的users表每个User实例代表users表中的一条记录"""# 指定表名(如果不指定,默认为类名的小写:user)__tablename__='users'# 字段定义id=Column(Integer,primary_key=True,autoincrement=True,comment='用户ID')username=Column(String(50),nullable=False,unique=True,comment='用户名')email=Column(String(100),nullable=False,unique=True,comment='邮箱')password_hash=Column(String(255),nullable=False,comment='密码哈希')full_name=Column(String(100),comment='真实姓名')avatar_url=Column(String(255),comment='头像URL')bio=Column(Text,comment='个人简介')# 时间戳字段created_at=Column(DateTime,default=datetime.now,comment='创建时间')updated_at=Column(DateTime,default=datetime.now,onupdate=datetime.now,comment='更新时间')# 状态字段is_active=Column(Integer,default=1,comment='是否激活:0-禁用,1-激活')is_verified=Column(Integer,default=0,comment='是否验证:0-未验证,1-已验证')def__repr__(self):"""对象的字符串表示,调试时非常有用"""returnf"<User(id={self.id}, username='{self.username}', email='{self.email}')>"defto_dict(self):"""将对象转换为字典(用于API返回)"""return{'id':self.id,'username':self.username,'email':self.email,'full_name':self.full_name,'avatar_url':self.avatar_url,'bio':self.bio,'created_at':self.created_at.isoformat()ifself.created_atelseNone,'updated_at':self.updated_at.isoformat()ifself.updated_atelseNone,'is_active':bool(self.is_active),'is_verified':bool(self.is_verified)}

3.2 字段类型详解

SQLAlchemy提供了丰富的字段类型,对应MySQL的数据类型:

Python/SQLAlchemy类型MySQL类型说明示例
IntegerINT整数id = Column(Integer)
String(length)VARCHAR(length)可变字符串username = Column(String(50))
TextTEXT长文本bio = Column(Text)
DateTimeDATETIME日期时间created_at = Column(DateTime)
BooleanTINYINT(1)布尔值is_active = Column(Boolean)
FloatFLOAT浮点数price = Column(Float)
NumericDECIMAL精确小数amount = Column(Numeric(10, 2))
LargeBinaryBLOB二进制数据file_data = Column(LargeBinary)

踩坑提醒:MySQL的BOOLEAN类型实际上就是TINYINT(1),SQLAlchemy的Boolean类型会自动做转换。但有些老版本的MySQL可能不支持,这时候用Integer更稳妥。

3.3 字段参数详解

每个Column都可以接受多种参数:

# 常见参数示例Column(Integer,# 字段类型primary_key=True,# 是否主键autoincrement=True,# 是否自增nullable=False,# 是否允许NULLunique=True,# 是否唯一default=0,# 默认值index=True,# 是否创建索引comment='用户ID'# 字段注释(MySQL 5.7+))

特别重要的参数

  • nullable:默认为True,但主键和业务关键字段应该设为False
  • default:可以是值,也可以是函数,如default=datetime.now
  • onupdate:记录更新时自动设置,如onupdate=datetime.now

四、创建数据库表

模型定义好了,现在需要把它同步到数据库中。

4.1 创建表的完整流程

创建create_tables.py

# create_tables.py - 创建数据库表importsysimportos# 添加项目根目录到Python路径sys.path.append(os.path.dirname(os.path.abspath(__file__)))fromsqlalchemyimportcreate_enginefrommodels.userimportBase,User# 数据库配置(实际项目应该从config导入)DATABASE_URL="mysql+pymysql://root:your_password@localhost:3306/orm_demo"defcreate_all_tables():"""创建所有表"""# 1. 创建引擎engine=create_engine(DATABASE_URL,echo=True)# 2. 创建所有表print("正在创建表...")Base.metadata.create_all(bind=engine)# 3. 验证表是否创建成功withengine.connect()asconn:# 查询数据库中所有表result=conn.execute("SHOW TABLES")tables=[row[0]forrowinresult]print(f"\n✅ 表创建完成!当前数据库中的表:")fortableintables:print(f" -{table}")# 查看users表结构if'users'intables:print(f"\n📋 users表结构:")result=conn.execute("DESC users")forrowinresult:print(f"{row[0]:20}{row[1]:20}{row[2]}")if__name__=="__main__":try:create_all_tables()exceptExceptionase:print(f"❌ 创建表失败:{e}")print("\n💡 可能的原因:")print("1. MySQL服务没有启动")print("2. 数据库不存在(需要先创建数据库)")print("3. 用户名或密码错误")print("4. 没有创建数据库的权限")

运行这个脚本,你应该能看到类似这样的输出:

正在创建表... 2024-01-15 10:30:00 INFO sqlalchemy.engine.Engine SHOW VARIABLES LIKE 'sql_mode' ... 2024-01-15 10:30:00 INFO sqlalchemy.engine.Engine CREATE TABLE users ( id INTEGER NOT NULL AUTO_INCREMENT, username VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, ... ) ✅ 表创建完成!当前数据库中的表: - users

4.2 表创建的背后原理

flowchart TD A[定义模型类<br>class User(Base)] --> B[收集元数据<br>Base.metadata] B --> C[生成CREATE TABLE语句<br>SQL编译] C --> D[连接数据库<br>engine.connect] D --> E[执行SQL语句<br>conn.execute] E --> F[提交事务<br>conn.commit] F --> G[表创建成功] H[模型类修改] --> I[表结构变更] I --> J{如何同步?} J --> K[Alembic迁移工具] J --> L[手动修改SQL]

重要提醒create_all()只会创建不存在的表,不会更新已存在的表结构。如果要修改表结构,需要使用迁移工具(如Alembic),这是很多新手容易踩的坑。

五、基本CRUD操作

表创建好了,现在我们来实际操作数据。

5.1 添加数据(Create)

# crud_create.py - 添加数据fromsqlalchemy.ormimportSessionfrommodels.userimportUserfromdatetimeimportdatetimeimportconfigdefcreate_user():"""创建新用户"""# 获取数据库会话session=config.DatabaseConfig.SessionLocal()try:# 创建User对象new_user=User(username="zhangsan",email="zhangsan@example.com",password_hash="hashed_password_123",# 实际项目要用bcrypt等库哈希full_name="张三",bio="我是张三,喜欢编程和篮球",avatar_url="https://example.com/avatar.jpg")# 添加到sessionsession.add(new_user)# 提交到数据库(实际执行INSERT)session.commit()print(f"✅ 用户创建成功!ID:{new_user.id}")# 刷新对象,获取数据库生成的ID等字段session.refresh(new_user)print(f" 完整信息:{new_user.to_dict()}")returnnew_userexceptExceptionase:# 发生错误时回滚session.rollback()print(f"❌ 创建用户失败:{e}")raisefinally:# 关闭sessionsession.close()defcreate_multiple_users():"""批量创建用户"""session=config.DatabaseConfig.SessionLocal()users_data=[{"username":"lisi","email":"lisi@example.com","password_hash":"hash_lisi","full_name":"李四"},{"username":"wangwu","email":"wangwu@example.com","password_hash":"hash_wangwu","full_name":"王五"}]try:users=[]fordatainusers_data:user=User(**data)session.add(user)users.append(user)# 一次性提交所有session.commit()print(f"✅ 批量创建成功,添加了{len(users)}个用户")foruserinusers:session.refresh(user)print(f" -{user.username}(ID:{user.id})")exceptExceptionase:session.rollback()print(f"❌ 批量创建失败:{e}")finally:session.close()if__name__=="__main__":# 创建单个用户user=create_user()# 批量创建create_multiple_users()

5.2 查询数据(Read)

查询是ORM最强大的功能之一:

# crud_read.py - 查询数据fromsqlalchemy.ormimportSessionfromsqlalchemyimportor_,and_frommodels.userimportUserimportconfigdefquery_users():"""各种查询示例"""session=config.DatabaseConfig.SessionLocal()try:print("=== 基本查询 ===")# 1. 查询所有用户all_users=session.query(User).all()print(f"1. 所有用户(共{len(all_users)}个):")foruserinall_users[:3]:# 只显示前3个print(f" -{user.username}({user.email})")# 2. 获取第一个用户first_user=session.query(User).first()print(f"\n2. 第一个用户:{first_user}")# 3. 根据ID查询(最常用)user_by_id=session.query(User).filter(User.id==1).first()print(f"\n3. ID为1的用户:{user_by_id}")# 4. 条件查询print("\n4. 条件查询:")# 查找所有激活的用户active_users=session.query(User).filter(User.is_active==1).all()print(f" 激活用户:{len(active_users)}个")# 查找用户名包含"zhang"的用户zhang_users=session.query(User).filter(User.username.like('%zhang%')).all()print(f" 用户名包含'zhang':{len(zhang_users)}个")# 5. 复杂条件(AND/OR)print("\n5. 复杂条件查询:")# AND条件:激活且已验证verified_active=session.query(User).filter(and_(User.is_active==1,User.is_verified==1)).all()print(f" 激活且已验证:{len(verified_active)}个")# OR条件:用户名为zhangsan或lisispecific_users=session.query(User).filter(or_(User.username=='zhangsan',User.username=='lisi')).all()print(f" zhangsan或lisi:{len(specific_users)}个")# 6. 排序和限制print("\n6. 排序查询:")# 按创建时间倒序,取前5个recent_users=session.query(User).order_by(User.created_at.desc()).limit(5).all()print(f" 最近创建的5个用户:")foruserinrecent_users:print(f" -{user.username}({user.created_at})")# 7. 计数user_count=session.query(User).count()print(f"\n7. 用户总数:{user_count}")# 8. 只选择特定字段print("\n8. 只查询用户名和邮箱:")user_info=session.query(User.username,User.email).all()forusername,emailinuser_info[:3]:print(f" -{username}:{email}")finally:session.close()if__name__=="__main__":query_users()

5.3 更新和删除(Update & Delete)

# crud_update_delete.py - 更新和删除fromsqlalchemy.ormimportSessionfrommodels.userimportUserimportconfigdefupdate_user():"""更新用户信息"""session=config.DatabaseConfig.SessionLocal()try:# 1. 先查询要更新的用户user=session.query(User).filter(User.username=='zhangsan').first()ifnotuser:print("❌ 用户不存在")returnprint(f"更新前:{user.to_dict()}")# 2. 修改对象属性user.full_name="张三(已更新)"user.bio="更新后的个人简介"user.is_verified=1# 3. 提交更改session.commit()session.refresh(user)# 刷新获取最新数据print(f"✅ 更新成功!")print(f"更新后:{user.to_dict()}")exceptExceptionase:session.rollback()print(f"❌ 更新失败:{e}")finally:session.close()defdelete_user():"""删除用户"""session=config.DatabaseConfig.SessionLocal()try:# 查找要删除的用户user=session.query(User).filter(User.username=='wangwu').first()ifnotuser:print("❌ 用户不存在")returnprint(f"要删除的用户:{user}")# 确认删除confirm=input("确认删除?(y/n): ")ifconfirm.lower()=='y':session.delete(user)session.commit()print("✅ 用户删除成功")else:print("取消删除")session.rollback()exceptExceptionase:session.rollback()print(f"❌ 删除失败:{e}")finally:session.close()if__name__=="__main__":update_user()delete_user()

六、高级特性:关系映射

真实的业务中,表之间是有关系的。比如用户有多个订单,订单属于一个用户。

6.1 一对多关系

让我们添加一个订单模型:

# models/order.py - 订单模型fromsqlalchemyimportColumn,Integer,String,Float,DateTime,ForeignKeyfromsqlalchemy.ormimportrelationshipfromdatetimeimportdatetimefrommodels.userimportBase# 使用同一个BaseclassOrder(Base):"""订单模型"""__tablename__='orders'id=Column(Integer,primary_key=True,autoincrement=True)order_no=Column(String(50),unique=True,nullable=False,comment='订单号')user_id=Column(Integer,ForeignKey('users.id'),nullable=False,comment='用户ID')amount=Column(Float,nullable=False,comment='订单金额')status=Column(String(20),default='pending',comment='订单状态')created_at=Column(DateTime,default=datetime.now)# 定义关系# back_populates表示双向关系user=relationship("User",back_populates="orders")def__repr__(self):returnf"<Order(id={self.id}, order_no='{self.order_no}', amount={self.amount})>"# 在User模型中添加反向关系# 修改models/user.py,在User类中添加:# orders = relationship("Order", back_populates="user")

6.2 关系查询

# relationship_demo.py - 关系查询示例fromsqlalchemy.ormimportSessionfrommodels.userimportUserfrommodels.orderimportOrderimportconfigimportrandomimportstringdefgenerate_order_no():"""生成随机订单号"""return'ORD'+''.join(random.choices(string.digits,k=10))defsetup_relationships():"""设置关系数据"""session=config.DatabaseConfig.SessionLocal()try:# 先清空数据(测试用)session.query(Order).delete()session.commit()# 获取一个用户user=session.query(User).first()ifnotuser:print("请先创建用户")return# 为用户创建3个订单foriinrange(3):order=Order(order_no=generate_order_no(),user_id=user.id,amount=round(random.uniform(100,1000),2),status=random.choice(['pending','paid','shipped','completed']))session.add(order)session.commit()print(f"✅ 为用户{user.username}创建了3个订单")exceptExceptionase:session.rollback()print(f"❌ 设置失败:{e}")finally:session.close()defquery_relationships():"""查询关系数据"""session=config.DatabaseConfig.SessionLocal()try:print("=== 关系查询演示 ===")# 1. 从用户查订单(一对多)user=session.query(User).first()print(f"\n1. 用户{user.username}的所有订单:")# 注意:这里需要先导入Order模型并建立关系# 为了演示,我们直接查询orders=session.query(Order).filter(Order.user_id==user.id).all()fororderinorders:print(f" - 订单号:{order.order_no}, 金额: ¥{order.amount}, 状态:{order.status}")# 2. 从订单查用户(多对一)print(f"\n2. 第一个订单的用户信息:")first_order=session.query(Order).first()iffirst_order:order_user=session.query(User).filter(User.id==first_order.user_id).first()print(f" 订单{first_order.order_no}属于用户:{order_user.username}")# 3. 连接查询(使用join)print(f"\n3. 连接查询(用户+订单):")results=session.query(User.username,Order.order_no,Order.amount).join(Order,User.id==Order.user_id).all()forusername,order_no,amountinresults[:5]:# 显示前5条print(f" 用户:{username}, 订单:{order_no}, 金额: ¥{amount}")finally:session.close()if__name__=="__main__":setup_relationships()query_relationships()
erDiagram USERS ||--o{ ORDERS : has USERS { integer id PK string username string email datetime created_at } ORDERS { integer id PK string order_no integer user_id FK float amount string status datetime created_at }

七、实际项目应用建议

经过上面的学习,你已经掌握了SQLAlchemy ORM的基础。但在实际项目中,还需要注意以下几点:

7.1 项目结构优化

real_project/ ├── app/ │ ├── models/ # 数据模型 │ │ ├── __init__.py # 导出所有模型 │ │ ├── user.py │ │ ├── order.py │ │ └── product.py │ ├── schemas/ # Pydantic模型(API验证) │ ├── crud/ # 业务逻辑层 │ ├── api/ # 路由层 │ └── database.py # 数据库配置 ├── alembic/ # 数据库迁移 ├── tests/ # 测试 └── requirements.txt

7.2 性能优化技巧

  1. 延迟加载 vs 立即加载

    # 延迟加载(默认):访问时再查询user=session.query(User).first()print(user.orders)# 这里才执行查询# 立即加载:一次性查询所有关联数据fromsqlalchemy.ormimportjoinedloaduser=session.query(User).options(joinedload(User.orders)).first()
  2. 批量操作

    # 不好的做法:循环插入foritemindata:session.add(Item(**item))# 好的做法:批量插入session.bulk_insert_mappings(Item,data)
  3. 索引优化

    fromsqlalchemyimportIndex# 创建复合索引idx=Index('idx_user_email',User.email,User.is_active)

7.3 常见错误与解决方案

错误现象可能原因解决方案
sqlalchemy.exc.IntegrityError违反唯一约束或外键约束检查数据唯一性,确保外键存在
sqlalchemy.exc.OperationalError数据库连接问题检查MySQL服务、网络、权限
AttributeError: 'NoneType'查询结果为空添加空值检查:if user:
性能慢,N+1查询问题循环中查询关联数据使用joinedloadselectinload
表结构修改不生效使用create_all不会更新表使用Alembic迁移工具

八、学习总结与进阶

恭喜你!已经完成了SQLAlchemy ORM的基础学习。让我们回顾一下今天的收获:

8.1 核心要点

  1. 模型定义:使用declarative_base()创建基类,定义类对应表
  2. 字段映射:掌握各种Column类型和参数
  3. CRUD操作:add/commit(增)、query/filter(查)、属性修改(改)、delete(删)
  4. 关系映射:一对多、多对一关系的定义和查询
  5. 会话管理:Session的生命周期管理

8.2 下一步学习方向

  1. 数据库迁移:学习Alembic,管理表结构变更
  2. 高级查询:子查询、窗口函数、原生SQL混合使用
  3. 性能优化:连接池配置、查询优化、缓存策略
  4. 异步支持:SQLAlchemy 1.4+的异步API
  5. 结合Web框架:在FastAPI或Flask中使用SQLAlchemy

学习交流与互动

欢迎在评论区分享你的学习体验:

  1. 你在定义第一个模型时遇到了什么问题?
  2. 文中的示例代码都运行成功了吗?
  3. 在实际项目中,你打算用SQLAlchemy做什么功能?
  4. 对于关系映射,还有什么不清楚的地方?

我会认真阅读每一条评论,并为初学者提供针对性的解答。记住,学数据库一定要多动手实践!

推荐学习资源:

  1. SQLAlchemy官方文档 - 最权威的参考资料
  2. SQLAlchemy教程 - 知乎专栏 - 中文教程,适合入门
  3. Alembic迁移教程 - 数据库迁移必备
  4. 《Python数据库编程实战》 - 系统学习数据库编程

下篇预告:
下一篇将分享《SQLAlchemy查询进阶:过滤、排序与聚合 - 手把手带你从基础查询到实战分析》,带你掌握复杂查询、性能优化和实际业务场景的应用。


最后的小建议:学习ORM就像学开车,刚开始觉得规则多、操作复杂,但一旦掌握,就能轻松到达目的地。今天的内容可能有点多,建议你分两天学习:

  • 第一天:掌握模型定义和基本CRUD
  • 第二天:学习关系映射和实际项目应用

遇到问题不要怕,每个优秀的开发者都是从踩坑开始的。我在学习SQLAlchemy时,曾经因为忘记session.commit()调试了一个下午!现在回想起来,这些都是宝贵的经验。

动手时间:打开你的编辑器,创建一个User模型,然后实现用户的增删改查。遇到问题?随时回来查阅本文,或者在评论区提问!

祝你学习愉快,编程进步! 🚀

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/23 14:00:18

OpenCode终极指南:5步掌握终端AI编程助手的核心功能

OpenCode终极指南&#xff1a;5步掌握终端AI编程助手的核心功能 【免费下载链接】opencode 一个专为终端打造的开源AI编程助手&#xff0c;模型灵活可选&#xff0c;可远程驱动。 项目地址: https://gitcode.com/GitHub_Trending/openc/opencode 想要在终端中体验AI编程…

作者头像 李华
网站建设 2026/2/26 6:56:14

洛雪音乐音源:3分钟快速部署全网音乐资源的终极方案

洛雪音乐音源&#xff1a;3分钟快速部署全网音乐资源的终极方案 【免费下载链接】lxmusic- lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/gh_mirrors/lx/lxmusic- 还在为寻找免费优质的音乐资源而烦恼吗&#xff1f;洛雪音乐音源项目为你提供了完美…

作者头像 李华
网站建设 2026/2/18 0:34:29

数据结构期末复习:递归与循环核心算法实战总结

数据结构期末复习&#xff1a;递归与循环核心算法实战总结期末冲刺必备&#xff01; 递归与循环是数据结构课程中的高频考点&#xff0c;也是编程思维训练的核心内容。本文结合三大经典问题&#xff08;阶乘、斐波那契、数组最小值查找&#xff09;&#xff0c;系统梳理递归与循…

作者头像 李华
网站建设 2026/2/27 19:48:06

基于Python+Django的进销存管理系统设计与实现

前言 &#x1f31e;博主介绍&#xff1a;✌CSDN特邀作者、全栈领域优质创作者、10年IT从业经验、码云/掘金/知乎/B站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发、文档编写、答疑辅导等。✌…

作者头像 李华
网站建设 2026/2/26 19:59:18

sklearn函数总结八—线性模型 逻辑回归

纯手打&#xff0c;代码整理中&#xff0c;持续更新中^-^序号延用总结七15、线性模型 逻辑回归15.1 定义线性模型用于分类的核心思想非常直观&#xff1a;试图找到一个线性决策边界&#xff08;在特征空间中是一条直线、一个平面或一个超平面&#xff09;&#xff0c;将不同类别…

作者头像 李华