首页/新闻资讯/正文详情

SQLAlchemy ORM:Python数据库操作全解析与实战

发布时间:2026/11/4 9:12:02 来源:云帆数科 栏目:资讯中心
SQLAlchemy ORM:Python数据库操作全解析与实战
1. Python数据库操作利器SQLAlchemy ORM深度解析作为Python开发者数据库操作是我们日常工作中不可或缺的一部分。SQLAlchemy作为Python生态中最强大的ORM工具之一它完美地平衡了灵活性与易用性。我在多个生产项目中深度使用SQLAlchemy后发现它远比表面看起来要强大得多。1.1 为什么选择SQLAlchemy在Python的ORM生态中SQLAlchemy和Django ORM是最常被比较的两个选择。Django ORM简单易用但灵活性有限而SQLAlchemy则提供了从简单到复杂的全方位解决方案。特别是在需要复杂查询、多数据库支持或高性能场景下SQLAlchemy的优势尤为明显。SQLAlchemy的核心优势在于它的分层设计最底层是核心的SQL表达式语言中间层是ORM功能最上层是各种扩展和工具这种设计使得开发者可以根据需求选择合适的使用方式从简单的CRUD到复杂的多表联合查询都能优雅处理。2. 环境准备与基础配置2.1 安装与数据库驱动选择安装SQLAlchemy非常简单但根据不同的数据库后端需要选择对应的驱动# 基础安装 pip install sqlalchemy # 按需选择数据库驱动 # PostgreSQL pip install psycopg2-binary # MySQL pip install mysql-connector-python # SQL Server pip install pyodbc # Oracle pip install cx_Oracle提示生产环境推荐使用psycopg2而非psycopg2-binary后者是为方便开发而设计的二进制分发版。2.2 数据库连接配置创建数据库连接是使用SQLAlchemy的第一步连接字符串的格式因数据库类型而异from sqlalchemy import create_engine # SQLite (内存数据库) engine create_engine(sqlite:///:memory:) # PostgreSQL engine create_engine(postgresql://user:passwordlocalhost:5432/mydb) # MySQL engine create_engine(mysqlmysqlconnector://user:passwordlocalhost:3306/mydb) # 启用连接池和日志 engine create_engine( postgresql://user:passwordlocalhost/mydb, pool_size10, max_overflow20, pool_timeout30, echoTrue # 输出SQL日志 )在实际项目中我建议将数据库配置放在单独的文件或环境变量中特别是密码等敏感信息。3. 数据模型定义的艺术3.1 基础模型定义SQLAlchemy使用声明式系统来定义模型这是我最欣赏的特性之一from sqlalchemy import Column, Integer, String, DateTime from sqlalchemy.ext.declarative import declarative_base from datetime import datetime Base declarative_base() class User(Base): __tablename__ users id Column(Integer, primary_keyTrue) username Column(String(50), uniqueTrue, nullableFalse) email Column(String(120), uniqueTrue) created_at Column(DateTime, defaultdatetime.utcnow) updated_at Column(DateTime, defaultdatetime.utcnow, onupdatedatetime.utcnow) def __repr__(self): return fUser(id{self.id}, username{self.username})注意__tablename__是必须的它指定了模型对应的数据库表名。__repr__方法虽然不是必须的但在调试时非常有用。3.2 高级字段类型与选项SQLAlchemy提供了丰富的字段类型和选项from sqlalchemy import Text, Boolean, Numeric, ForeignKey from sqlalchemy.dialects.postgresql import JSONB, ARRAY class Product(Base): __tablename__ products id Column(Integer, primary_keyTrue) name Column(String(100), indexTrue) # 添加索引提高查询速度 description Column(Text) # 长文本 price Column(Numeric(10, 2)) # 精确小数 is_active Column(Boolean, defaultTrue) tags Column(ARRAY(String)) # PostgreSQL数组类型 metadata Column(JSONB) # PostgreSQL JSON类型 category_id Column(Integer, ForeignKey(categories.id))在实际项目中我经常使用JSONB字段来存储灵活的结构化数据这在处理不确定结构的业务数据时特别有用。4. 关系建模实战技巧4.1 一对多关系一对多是最常见的关系类型比如用户和文章class User(Base): __tablename__ users id Column(Integer, primary_keyTrue) name Column(String(50)) articles relationship(Article, back_populatesauthor) class Article(Base): __tablename__ articles id Column(Integer, primary_keyTrue) title Column(String(100)) content Column(Text) author_id Column(Integer, ForeignKey(users.id)) author relationship(User, back_populatesarticles)这里的关键点是back_populates参数它建立了双向关系。你也可以使用backref简化代码articles relationship(Article, backrefauthor)4.2 多对多关系多对多关系需要中间关联表比如文章和标签# 关联表 article_tag Table(article_tag, Base.metadata, Column(article_id, Integer, ForeignKey(articles.id)), Column(tag_id, Integer, ForeignKey(tags.id)) ) class Article(Base): __tablename__ articles id Column(Integer, primary_keyTrue) tags relationship(Tag, secondaryarticle_tag, back_populatesarticles) class Tag(Base): __tablename__ tags id Column(Integer, primary_keyTrue) name Column(String(30)) articles relationship(Article, secondaryarticle_tag, back_populatestags)在实际项目中关联表有时需要额外字段这时可以将关联表也定义为模型class ArticleTag(Base): __tablename__ article_tag article_id Column(Integer, ForeignKey(articles.id), primary_keyTrue) tag_id Column(Integer, ForeignKey(tags.id), primary_keyTrue) created_at Column(DateTime, defaultdatetime.utcnow) article relationship(Article, backreftag_associations) tag relationship(Tag, backrefarticle_associations)5. 会话管理与CRUD操作5.1 会话生命周期管理SQLAlchemy的Session是数据库交互的核心接口正确管理会话生命周期至关重要from sqlalchemy.orm import sessionmaker Session sessionmaker(bindengine) # 最佳实践每个请求一个会话完成后关闭 def get_user(user_id): session Session() try: user session.query(User).get(user_id) return user finally: session.close() # 使用上下文管理器更优雅 from contextlib import contextmanager contextmanager def session_scope(): session Session() try: yield session session.commit() except: session.rollback() raise finally: session.close() # 使用示例 with session_scope() as session: new_user User(nameAlice) session.add(new_user)5.2 增删改查最佳实践创建(Create):# 单个创建 user User(nameBob, emailbobexample.com) session.add(user) session.commit() # 批量创建效率更高 session.add_all([ User(nameCharlie, emailcharlieexample.com), User(nameDavid, emaildavidexample.com) ]) session.commit()读取(Read):# 获取单个对象 user session.query(User).get(1) # 按主键查询 # 条件查询 active_users session.query(User).filter(User.is_active True).all() # 复杂查询 from sqlalchemy import or_ users session.query(User).filter( or_( User.name.like(A%), User.email.contains(example) ) ).order_by(User.created_at.desc()).limit(10).all()更新(Update):# 直接修改属性 user session.query(User).get(1) user.name New Name session.commit() # 批量更新 session.query(User).filter(User.is_active False).update( {is_active: True}, synchronize_sessionFalse ) session.commit()删除(Delete):# 单个删除 user session.query(User).get(1) session.delete(user) session.commit() # 批量删除 session.query(User).filter(User.is_active False).delete( synchronize_sessionFalse ) session.commit()6. 高级查询技巧6.1 连接查询优化# 基本连接 results session.query(User, Article).join(Article).filter(Article.published True).all() # 指定连接条件 results session.query(User).join(Article, User.id Article.author_id).all() # 多表连接 results (session.query(User, Article, Tag) .join(Article, User.id Article.author_id) .join(article_tag, Article.id article_tag.c.article_id) .join(Tag, article_tag.c.tag_id Tag.id) .filter(Tag.name Python) .all())6.2 聚合与分组from sqlalchemy import func # 简单计数 user_count session.query(func.count(User.id)).scalar() # 分组统计 article_stats (session.query( User.name, func.count(Article.id).label(article_count), func.max(Article.created_at).label(latest_article) ) .join(Article) .group_by(User.name) .all())6.3 子查询与CTE# 子查询 subq session.query(Article.author_id, func.count(*).label(article_count))\ .group_by(Article.author_id)\ .subquery() result session.query(User.name, subq.c.article_count)\ .join(subq, User.id subq.c.author_id)\ .all() # CTE (Common Table Expression) articles_cte session.query(Article)\ .filter(Article.published True)\ .cte(published_articles) result session.query(User, articles_cte)\ .join(articles_cte, User.id articles_cte.c.author_id)\ .all()7. 性能优化实战7.1 解决N1查询问题N1查询是ORM常见性能问题SQLAlchemy提供了几种解决方案# 问题示例获取所有用户及其文章N1查询 users session.query(User).all() for user in users: print(user.articles) # 每次访问都会产生一次查询 # 解决方案1joinedload (立即加载) from sqlalchemy.orm import joinedload users session.query(User).options(joinedload(User.articles)).all() # 解决方案2subqueryload (子查询加载) from sqlalchemy.orm import subqueryload users session.query(User).options(subqueryload(User.articles)).all() # 解决方案3selectinload (适合多对一关系) from sqlalchemy.orm import selectinload users session.query(User).options(selectinload(User.articles)).all()7.2 批量操作优化# 批量插入优化 # 低效方式 for i in range(1000): session.add(User(namefUser{i})) session.commit() # 高效方式 session.bulk_insert_mappings( User, [{name: fUser{i}} for i in range(1000)] ) session.commit() # 批量更新优化 session.bulk_update_mappings( User, [{id: i, name: fNewUser{i}} for i in range(1, 1001)] ) session.commit()8. 事务管理与隔离级别8.1 事务基础# 基本事务 try: user User(nameAlice) session.add(user) session.commit() except: session.rollback() raise # 嵌套事务 try: with session.begin_nested(): # 保存点 user1 User(nameBob) session.add(user1) with session.begin_nested(): user2 User(nameCharlie) session.add(user2) raise Exception(Oops) # 这个事务会回滚 session.commit() # user1会被提交user2不会 except: session.rollback()8.2 隔离级别配置from sqlalchemy import create_engine from sqlalchemy.engine.url import URL # PostgreSQL配置隔离级别 db_url URL.create( drivernamepostgresql, usernameuser, passwordpass, hostlocalhost, databasemydb, query{isolation_level: REPEATABLE READ} ) engine create_engine(db_url)9. 实际项目中的经验分享9.1 多数据库支持在大型项目中可能需要同时连接多个数据库# 主数据库 master_engine create_engine(postgresql://user:passmaster/db) # 从数据库 slave_engine create_engine(postgresql://user:passslave/db) # 会话工厂 MasterSession sessionmaker(bindmaster_engine) SlaveSession sessionmaker(bindslave_engine) # 读写分离策略 def get_session(read_onlyFalse): return SlaveSession() if read_only else MasterSession()9.2 分表分库策略对于大数据量表可以考虑分表策略from sqlalchemy.ext.declarative import declared_attr from sqlalchemy import event class ShardedUser(Base): declared_attr def __tablename__(cls): return users_%02d % (hash(cls) % 10) # 分成10个表 id Column(Integer, primary_keyTrue) name Column(String(50)) # 分表路由 event.listens_for(ShardedUser, before_insert) def receive_before_insert(mapper, connection, target): # 根据业务规则决定插入哪个表 target.__tablename__ fusers_{hash(target.name) % 10}9.3 常见陷阱与解决方案会话过期问题现象在长时间运行的会话中对象可能变为过期状态解决定期session.refresh()或重新查询循环导入问题现象模型之间存在循环引用导致导入错误解决使用字符串形式的类名如relationship(models.User)连接泄漏现象未关闭的会话导致连接池耗尽解决始终使用上下文管理器或try/finally确保会话关闭批量操作内存问题现象处理大量数据时内存激增解决使用yield_per分批处理for user in session.query(User).yield_per(100): process_user(user)10. 扩展与进阶10.1 混合属性混合属性可以在Python层面定义虚拟列from sqlalchemy.ext.hybrid import hybrid_property class User(Base): __tablename__ users id Column(Integer, primary_keyTrue) first_name Column(String(50)) last_name Column(String(50)) hybrid_property def full_name(self): return f{self.first_name} {self.last_name} full_name.expression def full_name(cls): return cls.first_name cls.last_name10.2 事件监听SQLAlchemy的事件系统非常强大from sqlalchemy import event event.listens_for(User, before_insert) def before_user_insert(mapper, connection, target): target.created_at datetime.utcnow() event.listens_for(User, before_update) def before_user_update(mapper, connection, target): target.updated_at datetime.utcnow() event.listens_for(engine, connect) def set_sqlite_pragma(dbapi_connection, connection_record): cursor dbapi_connection.cursor() cursor.execute(PRAGMA foreign_keysON) cursor.close()10.3 异步支持SQLAlchemy 1.4 提供了对异步IO的原生支持from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.future import select async def main(): engine create_async_engine(postgresqlasyncpg://user:passhost/db) async with AsyncSession(engine) as session: result await session.execute(select(User).where(User.name Alice)) user result.scalar_one() user.email newexample.com await session.commit()11. 测试策略11.1 单元测试配置import unittest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker class TestUserModel(unittest.TestCase): def setUp(self): self.engine create_engine(sqlite:///:memory:) Base.metadata.create_all(self.engine) self.Session sessionmaker(bindself.engine) def tearDown(self): Base.metadata.drop_all(self.engine) def test_user_creation(self): session self.Session() try: user User(nameTest) session.add(user) session.commit() fetched session.query(User).first() self.assertEqual(fetched.name, Test) finally: session.close()11.2 测试数据准备使用fixtures准备测试数据from sqlalchemy.orm import Session def create_test_data(session: Session): users [ User(nameAlice, emailaliceexample.com), User(nameBob, emailbobexample.com) ] session.add_all(users) session.commit() return users12. 部署注意事项连接池配置engine create_engine( postgresql://user:passhost/db, pool_size10, max_overflow20, pool_timeout30, pool_pre_pingTrue # 自动检测连接是否有效 )生产环境日志import logging logging.basicConfig() logging.getLogger(sqlalchemy.engine).setLevel(logging.WARNING)性能监控使用sqlalchemy.event监听查询执行时间集成APM工具如New Relic或Datadog数据库迁移使用Alembic进行数据库迁移管理避免直接使用Base.metadata.create_all()在生产环境13. 与Web框架集成13.1 Flask集成from flask import Flask from flask_sqlalchemy import SQLAlchemy app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] sqlite:///db.sqlite app.config[SQLALCHEMY_TRACK_MODIFICATIONS] False db SQLAlchemy(app) class User(db.Model): id db.Column(db.Integer, primary_keyTrue) name db.Column(db.String(50))13.2 FastAPI集成from fastapi import FastAPI, Depends from sqlalchemy.orm import Session app FastAPI() # 依赖项 def get_db(): db SessionLocal() try: yield db finally: db.close() app.get(/users/{user_id}) def read_user(user_id: int, db: Session Depends(get_db)): user db.query(User).filter(User.id user_id).first() return user14. 性能对比与调优14.1 ORM vs 核心SQL# ORM方式 users session.query(User).filter(User.name.like(A%)).all() # 核心SQL方式性能更高 from sqlalchemy import text result session.execute(text(SELECT * FROM users WHERE name LIKE A%)) users [dict(row) for row in result]14.2 性能调优技巧索引优化为常用查询条件添加索引考虑复合索引顺序查询优化只查询需要的列使用contains_eager优化特定场景的加载策略批量操作使用bulk_insert_mappings/bulk_update_mappings考虑使用COPY命令PostgreSQL缓存策略实现查询结果缓存使用Dogpile或Redis缓存常用查询15. 安全最佳实践SQL注入防护始终使用参数化查询避免直接拼接SQL字符串数据验证在模型层使用validates装饰器或在业务逻辑层进行验证敏感数据处理加密存储密码等敏感信息使用SQLAlchemy-Utils提供的字段类型权限控制实现行级安全PostgreSQL RLS或使用SQLAlchemy过滤器自动应用权限from sqlalchemy.orm import validates class User(Base): # ... validates(email) def validate_email(self, key, address): assert in address, Invalid email address return address16. 监控与维护16.1 查询性能分析from sqlalchemy import event import time event.listens_for(engine, before_cursor_execute) def before_cursor_execute(conn, cursor, statement, parameters, context, executemany): context._query_start_time time.time() event.listens_for(engine, after_cursor_execute) def after_cursor_execute(conn, cursor, statement, parameters, context, executemany): duration time.time() - context._query_start_time if duration 0.5: # 记录慢查询 logger.warning(fSlow query: {statement} took {duration:.2f}s)16.2 数据库健康检查def check_database_health(engine): try: with engine.connect() as conn: conn.execute(text(SELECT 1)) return True except Exception as e: logger.error(fDatabase health check failed: {e}) return False17. 未来发展与替代方案17.1 SQLAlchemy 2.0新特性全新API设计更一致的查询接口更好的类型提示支持性能改进更高效的语句编译减少内存使用异步IO原生支持不再需要额外扩展更简洁的异步API17.2 替代方案比较Django ORM优点简单易用与Django深度集成缺点灵活性有限不适合复杂查询Peewee优点轻量级API简洁缺点功能较少社区较小PonyORM优点独特的语法自动优化查询缺点学习曲线陡峭社区小TortoiseORM优点原生异步支持设计现代缺点相对年轻生态系统不够成熟18. 个人实战经验分享在实际项目中使用SQLAlchemy多年我总结了以下几点深刻体会会话管理是关键过早或过晚关闭会话都会导致问题使用上下文管理器是最可靠的方式理解SQL是基础即使使用ORM也要理解生成的SQL使用echoTrue查看实际执行的SQL性能问题多在N1查询学会识别和解决N1问题使用joinedload等策略优化不要过度使用ORM复杂报表或分析查询可能更适合原生SQLORM和核心SQL可以混合使用测试要全面特别是事务相关逻辑考虑并发场景下的行为迁移要谨慎使用Alembic管理数据库变更生产环境变更前充分测试最后SQLAlchemy是一个需要时间掌握的工具但一旦精通它能成为你处理数据库操作最得力的助手。我建议从简单项目开始逐步探索它的各种高级特性最终你会发现自己能够优雅地处理各种复杂的数据库操作场景。

相关推荐

Qwen3-ASR-0.6B企业级离线部署与推理调优实战
Qwen3-ASR-0.6B企业级离线部署与推理调优实战

上个月帮一个做客服质检的团队收拾烂摊子:他们原本把通话录音往外送,做转写再抽检,后来合规口径一收紧,整条链路必须搬回内网,而且要在完全没有外网的环境里跑起来。他们选型时把目光放在Qwen3-ASR-0.6B上——0.6B 这个… · 2026/11/4 9:12:02

企业内网离线语音识别:Qwen3-ASR-0.6B部署与优化
企业内网离线语音识别:Qwen3-ASR-0.6B部署与优化

1. 为什么要在企业内网离线部署一个0.6B的语音识别模型先说结论:在企业里做语音转写这件事,最麻烦的通常不是识别准不准,而是音频不能离开内网。客服通话录音、内部会议记录、产线质检的语音指令、医疗问诊的对话留档,这些音频素材… · 2026/11/4 9:12:02

AgentScope 2.0多智能体框架落地实践:从消息编排到RAG服务化
AgentScope 2.0多智能体框架落地实践:从消息编排到RAG服务化

最近两个月我一直在折腾多智能体框架,从LangChain到CrewAI再到AutoGen,最后真正落进生产环境的,反而是一开始没太在意的AgentScope。不夸张地说,这套系统解决了我在实际项目里最头疼的几个问题:多Agent之间的消息怎么管… · 2026/11/4 9:11:00

Voxtral TTS:3秒语音克隆技术的突破与应用
Voxtral TTS:3秒语音克隆技术的突破与应用

1. 语音克隆技术的新里程碑:Voxtral TTS深度解析上周测试Mistral AI最新发布的Voxtral TTS时,我用同事的3秒语音片段生成了几乎无法辨别的克隆音频,连他本人都震惊得说不出话。这个突破性的语音合成系统正在彻底改变我们对声音复制的认知边界… · 2026/11/4 17:08:00

BDU技术演进:从电池开关到ASIL-D级安全核心
BDU技术演进:从电池开关到ASIL-D级安全核心

简介:本资源是一份聚焦电池包断路单元(BDU)领域的专业行业研究报告,面向新能源汽车零部件研发工程师、电池系统集成商、行业分析师及高校相关专业研究者,用于快速掌握BDU全球市场格局、技术演进趋势与头部厂商竞争态势… · 2026/11/4 17:08:00

强化学习KL散度:约束、正则还是度量?策略优化中的正确用法与调参经验
强化学习KL散度:约束、正则还是度量?策略优化中的正确用法与调参经验

强化学习里的KL散度,是个特别容易被“用错但看起来没错”的东西。我见过不少做策略优化的朋友,代码里加了一行KL惩罚项,训练日志上KL值也确实在动,但策略该崩还是崩,该不收敛还是不收敛。问题往往不在KL本身&#xff0… · 2026/11/4 17:08:00

从Demo到商用:智能体开发的任务编排与评测体系实战
从Demo到商用:智能体开发的任务编排与评测体系实战

商用智能体开发这两年从“Demo 满天飞”走到“能真正收钱”的阶段,中间隔着的坑比大多数人想象的多得多。我前后参与过几个对外交付的智能体项目,有给电商做售后自动处理的,有给内容团队做选题调研的,也有给传统企业做内部知识问答… · 2026/11/4 17:08:00

Vue3虚拟DOM原理与性能优化实战
Vue3虚拟DOM原理与性能优化实战

1. Vue3虚拟DOM机制深度解析作为一名长期奋战在前端开发一线的工程师,我深知虚拟DOM技术在现代前端框架中的核心地位。今天我们就来彻底拆解Vue3的虚拟DOM实现机制,这可能是目前最深入、最实用的Vue3虚拟DOM解析指南。Vue3的虚拟DOM系统经历了彻底重构&a… · 2026/11/4 17:08:00

SplitFed:联邦学习与拆分学习的架构级融合
SplitFed:联邦学习与拆分学习的架构级融合

1. 为什么“SplitFed”不是联邦学习的简单升级,而是架构级重构? “SplitFed实战解析:联邦学习与拆分学习的融合创新”——这个标题里藏着一个常被误读的关键点:它不是“联邦学习拆分学习11”,而是把两个原本运行在不同… · 2026/11/4 17:06:59

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38

AI辅助技术栈评估:提升研发决策效率60%
AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17

从生成Token到直接决策:Jev如何重塑AI Agent工程实践
从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17

32G统一内存跑大模型:内存账、TPS实测与端云分流
32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码