数据分析agent(十三_2):业务层和持久层相互转换mapper
二,属性 解释role:Mapped[str]mapped_column( String(32), comment列类别 (primary_key,forergn_key,measure,dimension) ) role: Mapped[str]Python 类型注解 Mapped 是 SQLAlchemy 提供的一个泛型类型用于在声明式模型中标注该属性在 Python 中的数据类型。 Mapped[str] 表示这个字段在 Python 层面是一个字符串类型。SQLAlchemy 会根据这个类型提示自动推断出对应的数据库数据类型如果不显式指定的话以及该列是否允许为 NULL。 mapped_column(...)数据库列配置 这个函数用于描述该列在数据库中的具体约束和规格。 String(32)显式指定了数据库中的数据类型为 VARCHAR且最大长度限制为 32 个字符。如果这里不传参数SQLAlchemy 会默认使用 Mapped[str] 推导出的类型但显式指定长度是更严谨的做法。 comment列类别...为该数据库字段添加注释说明。这在生成数据库 DDL如 CREATE TABLE 语句时会作为列注释写入数据库有助于后续维护时理解该字段的业务含义。 primary_key (主键) 代表该列是表的主键用于唯一标识表中的每一行记录。 forergn_key (外键) 注这里存在一个拼写错误正确的英文应该是 foreign_key。 代表该列是外键用于关联其他表建立表与表之间的关系。 measure (度量) 在数据仓库中度量通常指可被聚合计算的数值型数据。例如销售额、利润、订单数量、温度等。它们通常用于图表中的 Y 轴或指标卡片。 dimension (维度) 维度是指用于观察和分析数据的上下文或分类属性。例如时间年/月/日、地区、产品类别、客户名称等。它们通常用于图表中的 X 轴、分组Group By或筛选器。三各层的数据例子 column 列 来举例1业务层和应用层web,小程序 等交互的column_info.py:# 列对象 的类业务层用来表示 各个列 的对象 的封装 # 8给 个属性 from dataclasses import dataclass from typing import Any dataclass class ColumnInfo: id:str name:str type:str # 列 数据类型 role:str # 列类别 ( # primary_key 主键,forergn_key 外键 ,measure 度量:数值,dimension 维度:维度表中的属性 examples:list[Any] # 数据示例 description:str alias:list[str] table_id:str2,持久层和数据库交互的 column_info_mysql.pyfrom sqlalchemy.orm import Mapped, mapped_column from day05_Info_model.models.base import Base from sqlalchemy import String,Text from sqlalchemy.types import JSON class ColumnInfoMySQL(Base): __tablename__ coloumn_info id:Mapped[str]mapped_column( String(64), primary_keyTrue, comment列的编号 ) name:Mapped[str |None]mapped_column( String(128), comment列名称 ) type:Mapped[str | None]mapped_column( String(64), comment列 数据类型 ) role:Mapped[str | None]mapped_column( String(32), comment列类别 (primary_key 主键,forergn_key 外键 ,measure 度量:数值,dimension 维度:维度表中的属性 ) ) examples:Mapped[dict| list | None]mapped_column( JSON, comment列对象的 举例说明,数据示例 ) description:Mapped[str |None]mapped_column( Text, comment列 的 描述 说明是做什么的 ) alias:Mapped[dict | list | None]mapped_column( JSON, comment列别名 ) table_id:Mapped[str | None]mapped_column( String(64), comment列 所在的 对应的表 的编号 id )3,业务层和持久层的相互转换column_info_mapper.py:from dataclasses import asdict from day05_Info_model.entities.column_info import ColumnInfo from day05_Info_model.models.coloumn_info_mysql import ColumnInfoMySQL class ColumnInfoMapper: staticmethod def to_entity(column_info_mysql:ColumnInfoMySQL)-ColumnInfo: return ColumnInfo( idcolumn_info_mysql.id, namecolumn_info_mysql.name, typecolumn_info_mysql.type, rolecolumn_info_mysql.role, examplescolumn_info_mysql.examples, descriptioncolumn_info_mysql.description, aliascolumn_info_mysql.alias, table_idcolumn_info_mysql.table_id ) staticmethod def to_model(column_info:ColumnInfo)-ColumnInfoMySQL: return ColumnInfoMySQL(**asdict(column_info))四mapper:业务层和持久层转换 验证测试11_column_mapper_test.py:# main_test.py from dataclasses import asdict from day05_Info_model.entities.column_info import ColumnInfo from day05_Info_model.models.coloumn_info_mysql import ColumnInfoMySQL from day05_Info_model.mappers.column_info_mapper import ColumnInfoMapper # 1. 构造业务层对象 (Entity) entity ColumnInfo( idcol_001, namesales_amount, typeDECIMAL(10,2), rolemeasure, examples[199.99, 250.00], description销售总金额, alias[销售额, 营收], table_idtbl_order ) print( 1. 原始业务实体 (Entity) ) print(entity) # 触发 dataclass 的 __repr__ print() # 2. Entity - Model (业务层转持久层) model ColumnInfoMapper.to_model(entity) print( 2. 转换后的数据库模型 (Model) ) print(model) # 触发 SQLAlchemy 声明式对象的 __repr__ print() # 3. Model - Entity (持久层转回业务层) new_entity ColumnInfoMapper.to_entity(model) print( 3. 转换回业务实体 (Entity) ) print(new_entity) 1. 原始业务实体 (Entity) ColumnInfo(idcol_001, namesales_amount, typeDECIMAL(10,2), rolemeasure, examples[199.99, 250.0], description销售总金额, alias[销售额, 营收], table_idtbl_order) 2. 转换后的数据库模型 (Model) day05_Info_model.models.coloumn_info_mysql.ColumnInfoMySQL object at 0x00000210DB15AD50 3. 转换回业务实体 (Entity) ColumnInfo(idcol_001, namesales_amount, typeDECIMAL(10,2), rolemeasure, examples[199.99, 250.0], description销售总金额, alias[销售额, 营收], table_idtbl_order) 2,2_test_column_info_mapper.py:# test_column_info_mapper.py import unittest from day05_Info_model.entities.column_info import ColumnInfo from day05_Info_model.models.coloumn_info_mysql import ColumnInfoMySQL from day05_Info_model.mappers.column_info_mapper import ColumnInfoMapper class TestColumnInfoMapper(unittest.TestCase): def setUp(self): 测试前的准备工作构造一个标准的业务实体 self.entity ColumnInfo( idcol_001, namesales_amount, typeDECIMAL(10,2), rolemeasure, examples[199.99, 250.00], description销售总金额, alias[销售额, 营收], table_idtbl_order ) def test_to_model(self): 测试业务实体 - 数据库模型 model ColumnInfoMapper.to_model(self.entity) # 验证类型转换是否正确 self.assertIsInstance(model, ColumnInfoMySQL) # 验证字段值是否完全一致 self.assertEqual(model.id, col_001) self.assertEqual(model.name, sales_amount) self.assertEqual(model.type, DECIMAL(10,2)) self.assertEqual(model.role, measure) self.assertEqual(model.examples, [199.99, 250.00]) self.assertEqual(model.description, 销售总金额) self.assertEqual(model.alias, [销售额, 营收]) self.assertEqual(model.table_id, tbl_order) def test_to_entity(self): 测试数据库模型 - 业务实体 # 模拟从数据库查出来的对象这里用字典模拟 SQLAlchemy 对象的行为 class MockDBModel: def __init__(self): self.id col_002 self.name user_name self.type VARCHAR(64) self.role dimension self.examples [Alice, Bob] self.description 用户姓名 self.alias [姓名] self.table_id tbl_user mock_model MockDBModel() entity ColumnInfoMapper.to_entity(mock_model) # 验证类型转换是否正确 self.assertIsInstance(entity, ColumnInfo) # 验证字段值 self.assertEqual(entity.id, col_002) self.assertEqual(entity.role, dimension) self.assertEqual(entity.alias, [姓名]) def test_round_trip_conversion(self): 测试双向转换Entity - Model - Entity确保数据不丢失 model ColumnInfoMapper.to_model(self.entity) converted_entity ColumnInfoMapper.to_entity(model) # 验证经过一轮转换后数据是否和原始实体一致 self.assertEqual(self.entity.id, converted_entity.id) self.assertEqual(self.entity.name, converted_entity.name) self.assertEqual(self.entity.examples, converted_entity.examples) self.assertEqual(self.entity.alias, converted_entity.alias) if __name__ __main__: unittest.main() 点击pycharm运行弹出这样的窗口 这个错误 Error: Provide a qualified name of a function, class or module 是因为 PyCharm 的运行配置中模块路径Module Name填写的格式不对。 PyCharm 试图把你输入的长字符串当作一个“模块”去加载但它包含了类名和方法名导致 Python 找不到这个模块。 ✅ 解决方法二选一 方法一修改当前配置推荐 请按照以下步骤调整你截图中的设置 切换模式将下拉菜单从 module 改为 Script path脚本路径。 选择文件点击右侧的文件夹图标 选择你的测试文件 2_test_column_info_mapper.py。 指定特定测试可选如果你想只运行这一个特定的测试方法在下方的 Additional arguments附加参数框中输入 text 编辑 TestColumnInfoMapper.test_to_entity 点击 Run。 方法二最简单的“懒人”办法 不需要打开这个复杂的配置窗口 关闭当前的 Edit Configuration 窗口。 回到代码编辑界面。 在代码左侧的行号栏旁边找到 class TestColumnInfoMapper 或者 def test_to_entity 左边的 绿色三角形图标 ▶️。 直接点击那个绿色三角形选择 Run Unittests in ...。 PyCharm 会自动为你生成正确的配置并运行。 为什么会报错原理解析 在你截图的配置中 Type: 选择了 module这意味着后面只能填类似 unittest 或 my_package.my_module 这种纯包路径。 Name: 你填了 ...TestColumnInfoMapper.test_to_entity。 Python 会尝试执行 import ...TestColumnInfoMapper.test_to_entity这显然是不合法的导入语法所以它提示你需要提供一个合法的“函数、类或模块名称”。 如果改完还报错可以把新的报错截图发给我看看。

相关新闻

gen_smtp安全配置:STARTTLS与多种认证方式的最佳实践

gen_smtp安全配置:STARTTLS与多种认证方式的最佳实践

gen_smtp安全配置:STARTTLS与多种认证方式的最佳实践 【免费下载链接】gen_smtp The extensible Erlang SMTP client and server library. 项目地址: https://gitcode.com/gh_mirrors/ge/gen_smtp 在当今数字化时代,邮件传输的安全性至关重要。ge…

2026/7/28 8:32:09阅读更多 →
数据分析agent(十三):业务层和持久层的mapper相互转换

数据分析agent(十三):业务层和持久层的mapper相互转换

一,导入 数据库表1,强制删除名为 my-mysql 的容器docker rm -f my-mysql重新创建并启动新容器docker run -d --name my-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORDhappy123 mysql:8.0.41 方法二:先停止,再删除(常规操…

2026/7/28 8:32:09阅读更多 →
ESP32、Arduino与树莓派:三大开源硬件平台选型与智能小车实战指南

ESP32、Arduino与树莓派:三大开源硬件平台选型与智能小车实战指南

1. 从“世界首辆特斯拉Cybertruck警车”到创客的“智能小车”:一个关于硬件创新的平行叙事 最近,关于“世界首辆特斯拉Cybertruck警车”的新闻在科技和汽车圈刷了屏。这辆棱角分明、充满未来感的电动皮卡,被改装成警用巡逻车,其背…

2026/7/28 8:30:08阅读更多 →
Claude Design:从副项目到百万人使用的工具,AI 时代设计师的破局之路

Claude Design:从副项目到百万人使用的工具,AI 时代设计师的破局之路

Claude Design:卷出来的「副项目」Claude Design 竟是一个卷出来的「副项目」,它的背后是两个工程师和一个设计师之间的故事。故事始于 2025 年 11 月 Opus 4.5 的发布,那时 Nate Parrott 是 Claude Code 那个 VS Code 项目里唯一的设计师&am…

2026/7/28 9:40:55阅读更多 →
“百镜大战”雷声大雨点小,智能眼镜厂商为何纷纷舍弃高性能选择轻量化?

“百镜大战”雷声大雨点小,智能眼镜厂商为何纷纷舍弃高性能选择轻量化?

智能眼镜“待爆”,轻量化成新趋势2024年末起消费电子领域就流传“百镜大战”预言,然而一年半过去,智能眼镜品类仍雷声大雨点小。从业者认为“轻量化、长续航、高性能”的不可能三角是阻碍,当下智能眼镜产品出现分化,放…

2026/7/28 9:40:55阅读更多 →
AI联盟与Anthropic技术路线解析:开发者选型指南

AI联盟与Anthropic技术路线解析:开发者选型指南

最近AI圈有个很有意思的现象:OpenAI牵头成立了一个"AI联盟",拉上了微软、谷歌、Meta等一众大厂,但偏偏缺了一个重量级玩家——Anthropic。这背后到底发生了什么?为什么Claude的创造者选择单飞?如果你以为这只…

2026/7/28 9:40:55阅读更多 →
Dart语言基础语法快速入门与实战技巧

Dart语言基础语法快速入门与实战技巧

1. Dart语言基础语法快速入门作为一名从Java/Kotlin转向Flutter开发的程序员,我深刻理解学习新语言时的痛点。Dart作为Flutter的官方语言,其语法设计既保留了面向对象语言的严谨性,又融入了现代语言的简洁特性。下面我将用实际代码示例带你快…

2026/7/28 9:40:55阅读更多 →
Greasy Fork用户脚本平台:浏览器功能增强与网页定制化解决方案

Greasy Fork用户脚本平台:浏览器功能增强与网页定制化解决方案

Greasy Fork用户脚本平台:浏览器功能增强与网页定制化解决方案 【免费下载链接】greasyfork An online repository of user scripts. 项目地址: https://gitcode.com/gh_mirrors/gr/greasyfork Greasy Fork是一个功能强大的在线用户脚本仓库平台,…

2026/7/28 9:40:55阅读更多 →
Jetson Nano I2C OLED屏幕驱动实战:从原理到动态信息显示

Jetson Nano I2C OLED屏幕驱动实战:从原理到动态信息显示

1. 项目概述:在Jetson Nano上点亮一块小屏幕如果你手头有一块NVIDIA Jetson Nano 2GB开发者套件,并且对嵌入式开发、物联网或者机器人项目感兴趣,那么你大概率会遇到一个需求:如何让这块强大的边缘计算板“开口说话”,…

2026/7/28 9:38:55阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/27 16:57:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →