Kettle资源库实战:从文件混乱到团队协作的演进
前阵子朋友问我Kettle里到底要不要用资源库他说自己一直把转换文件.ktr和作业.kjb放在网盘里用的时候下载下来改改完再传回去结果一天到晚在弄版本冲突有时候自己刚调好的流程被同事一覆盖就全乱了。我听完就笑了这不就是几年前的我吗要知道Kettle现在也叫 Pentaho Data Integration虽然只是个 ETL 工具可一旦数据接入、清洗、汇总的转换数量超过几十个团队又不止一个人开发光靠本地文件和网盘共享迟早会翻车。今天这篇笔记就以“资源库”为主题把我们踩过的坑、用顺手的配置方式、以及真实项目中总结出来的经验写出来希望给准备入坑或已经在用 Kettle 的朋友一点参考。这篇文章不会只讲“资源库是什么”而是会把选型思路、从零配置、日常用法还有排查问题串起来讲。不管你之前用的是文件还是资源库都能找到能直接抄作业的内容。1. 为什么 Kettle 要引入“资源库”而不是用文件如果你只用 Kettle 做一两个小转换比如读个 Excel 导到 MySQL那确实用不上资源库文件方式反而更方便。但项目一旦复杂起来文件方式的短板就特别明显。1.1 文件方式带来的混乱用 .ktr/.kjb 文件作为唯一存储时最大的问题不是文件多而是“没有中央约束”。我见过最夸张的情况是一个目录下躺着三十多个名字相近的转换比如 test_new.ktr、test_final.ktr、test_final_20230201.ktr根本分不清哪个是生效版本。加上 Kettle 转换里经常直接记录数据库连接信息如果哪一天数据库密码到期了你得挨个打开所有转换去改连接配置改完还要小心别把文件弄坏这个工作量真的很让人头疼。更麻烦的是团队协作。假设你和同事同时改同一个作业文件传来传去总有人拿着旧版覆盖新版。Kettle 本身在文件模式下没有冲突检测也没有权限概念谁都能打开整个文件改等出了问题都不知道怎么回溯。我刚开始做项目时就是这种状态那会儿心里一直悬着生怕生产上的任务出问题。1.2 资源库到底解决什么问题资源库本质上就是一个“中央仓库”里面存的不再是散落的本文件而是转换、作业、数据库连接、共享参数这些元数据。你可以把资源库类比成项目的代码仓库只不过它服务的是 Kettle 对象。有了资源库开发人员通过 Spoon 连接到同一个仓库看到的目录结构和对象都是统一版本。在这个仓库里可以建文件夹做模块划分可以锁定某个作业防止别人误改还能查看对象的历史版本。如果误改或者改坏了能够回滚到之前可用版本。数据库连接也能集中维护大家共享同一个连接配置改密码只需要改一处所有引用了这个连接的转换都跟着生效——这一点在文件模式下几乎无法做到。资源库并不是强制要求它更像一个“团队协作的保险”。如果项目周期长、多人开发、对象数量多我建议你直接上资源库能帮你省掉一大堆低级麻烦。2. 资源库类型怎么选数据库资源库与文件资源库的区别Kettle 里的资源库并不是只有一种。早期大家用的都是“数据库资源库”新版本又加入了“文件资源库”。很多初学者第一次配置时容易懵这里把两者讲清楚。2.1 数据库资源库Database Repository数据库资源库的存储原理是在某个数据库里建立一组以 R_ 开头的表Kettle 把这些对象的元数据、XML 内容、版本记录等全部序列化到关系表中。连接资源库时Spoon 通过 JDBC 读取这些表再还原成转换和作业。这种方式的优点首先是稳定数据都在数据库里天然支持并发访问和权限控制。其次是适合团队协作多个开发人员可以同时登录同一个资源库配合文件夹权限和对象锁定机制能比较有效地避免互相覆盖。缺点是必须额外准备一个数据库并且建表初期的连接配置、字符集处理如果没做好后面容易出现各种连接或乱码问题。2.2 文件资源库File Repository新版本的 Kettle我记得从 8.2 左右开始引入支持在文件系统里创建一个资源库目录对象以 JSON/XML 形式保存在文件夹结构中。这种模式保留了资源库的“中央仓库”体验但实际上你面对的还是文件只不过多了层级和索引。文件资源库最大的好处是轻量、迁移方便。你不需要专门搭数据库同一个目录直接拷贝到另一台机器能继续用。另外一个隐藏优势是它天然适合用 Git 做版本管理因为底层就是文件可以 diff、合并、提交。不过对应的当多人同时操作同一个文件时它依然存在覆盖风险权限控制也比较弱更适合个人或小团队在开发环境使用。2.3 选型建议对比维度数据库资源库文件资源库存储介质关系数据库如 MySQL、Oracle、PostgreSQL文件系统目录适合规模中大型团队、生产环境个人、小团队、本地开发版本管理内置版本历史弱版本功能可依赖 Git并发协作较好有锁机制较差部署复杂度需要额外数据库低复制即可典型版本所有常见版本均支持Kettle 8.2 才支持所以结论很直接做个人学习、本地开发、想用 Git 管文件用文件资源库舒服如果是生产环境、多人协作、对象数量多还是老老实实上数据库资源库。我自己通常的开发流是开发机用文件资源库测试和生产环境用数据库资源库。3. 从零配置一个数据库资源库实操这里我用社区版 Kettle 9.4 / 10.x 为例讲一下数据库资源库的完整配置流程。版本号不同菜单名称可能略有差异但核心逻辑都一样。3.1 下载安装与启动的注意事项Kettle 社区版PDI可以直接从官网下载解压后里面有个 Spoon.bat/Spoon.sh启动前需要确保本机装了 Java JDK 8 或更高版本。启动后如果出现右上角的 Connect 图标说明运行正常。我不在这里花太多篇幅讲安装因为网上“kettle 下载安装教程”很多但有一点要提醒你Kettle 对 JDK 版本兼容性敏感我遇到过 JDK 17 和某些版本的 PDI 跑不起来的情况如果启动异常优先排查 Java 版本别折腾半天最后是环境问题。3.2 创建数据库资源库的步骤先准备一个数据库。比如我要在 MySQL 里建资源库就执行建库语句比如CREATE DATABASE kettle_repo DEFAULT CHARACTER SET utf8mb4;。字符集建议直接用 utf8mb4避免后续中文对象名或注释乱码。启动 Spoon点击右上角的 Connect 图标或者菜单栏 File - Connect打开资源库管理窗口。在资源库列表里点击“新建”选择类型为 Database Repository。弹窗里会让你填 Repository Name这个名字自己定比如 “dev_repo”。接下来配置数据库连接。点击“新建”或“编辑”选择数据库类型 MySQL填主机、端口、数据库名、用户名、密码先测试连接确认能通。第一次使用这个资源库需要在资源库管理窗口里点击“初始化版本”或“Init or Upgrade Repository”按钮让 Kettle 在数据库里自动创建 R_ 开头的表结构。这一步需要你填的数据库账号有建表权限。初始化完成后Kettle 会提示创建初始管理员账号一般是 admin/admin。然后点击连接输入 admin 和密码就能进入资源库界面了。进入之后你会发现左边的树形结构变成资源库目录而不是本地文件路径。在这里右击根目录可以新建文件夹、新建转换、导入对象。到这里一个最基本的数据库资源库就落地了。3.3 配置 JNDI 数据源可选但推荐很多人在资源库里建数据库连接时会直接把连接信息写死在资源库里。这有个问题开发、测试、生产环境的主机密码通常不一样如果每个环境都维护一份资源库连接信息跟着环境变配置管理就会很痛苦。更优雅的做法是用 JNDI 数据源。Kettle 社区版里支持通过jdbc.properties和simple-jndi机制配置 JNDI 数据源。在 Kettle 安装目录的simple-jndi子目录下有jdbc.properties文件在里面配置连接信息比如mysql_kettle/typejavax.sql.DataSource mysql_kettle/drivercom.mysql.cj.jdbc.Driver mysql_kettle/urljdbc:mysql://192.168.1.10:3306/kettle_dw?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghai mysql_kettle/useretl_user mysql_kettle/passwordyour_password然后在数据库连接类型里选择“JNDI”填写 JNDI 名称例如mysql_kettle。这样资源库里保存的只是一个 JNDI 名称真正的连接参数卸载环境配置档里。切换环境时只需要改这台机器上的jdbc.properties资源库里的转换不用动。我自己很喜欢这个方式尤其是在多环境部署时能省很多调整连接的时间。3.4 将已有文件资源导入资源库如果你的项目之前全是 .ktr/.kjb 文件现在转到资源库可以直接导入。在资源库目录中右键想要放入的文件夹选择“导入”然后选择本地文件或文件夹。Kettle 会自动把转换、作业以及内部的数据库连接元数据一起导入。导入之后有几个点要检查一是转换里如果引用了本机路径的外部文件比如 CSV 输入路径这些绝对路径要改成变量或统一目录否则换机器会报错。二是现有的作业里如果通过作业项调用本地 .ktr 文件导入后最好是重新选择为资源库中的对象让作业项指向资源库内部路径这样才能发挥资源库统一管理的价值。最后记得在资源库中把根目录按项目重新整理一下别把旧文件一股脑丢进去不然只是把混乱从文件系统搬进了资源库。4. 资源库的日常使用技巧资源库建好了真正难的是怎么用得顺手。这里分享几个我实测下来提高效率的方式。4.1 目录结构设计与命名规范在资源库里目录结构就是你的“项目结构”。我习惯按照业务分层或者数仓主题来建比如/ods、/dw、/dm或者按项目模块/订单、/用户、/公共。根目录下放一个“公共”文件夹专门存放共用的转换和数据库连接。命名上别再用test、new、final这种词一率用“目标表名_业务含义_频率”的格式比如ods_order_full_daily。资源库的对象是可以被作业引用的目录越清晰越不会被引用乱掉。多人协作时建议把每个人负责的模块锁定。选中某个转换或作业右键可以“锁定/锁定”这样其他人只能查看不能修改。虽然这个锁不是特别严格但它确实能防止大部分误改。4.2 在作业中引用资源库中的转换资源库模式下作业项里的“转换”步骤可以选择“资源库”作为对象来源直接浏览选择资源库里的转换。这样做的好处是作业和转换之间的关联是逻辑关系不会因为某个转换文件移动位置而断掉。如果作业和转换都在同一个资源库里搬迁到其他环境时整个树形目录迁移即可作业的引用关系通常能保留。有时候需要获取当前作业所在目录下的资源库路径可以用金丝雀变量比如${Internal.Transformation.Filename.Directory}在文件模式可用资源库模式下则可以用 Repository Directory 相关的变量。不过我更推荐直接用绝对资源库路径比如/订单/作业/ods_order_main.kjb反而更直观。4.3 真实业务场景多表合并、批量遍历日期、时间参数看这几个热搜词就知道大家在实际开发里经常遇到这几类问题“kettle 多表合并抽到一个表”、“kettle 批量遍历日期查数”、“kettle 转换里的时间参数在哪里”。其实这些场景在资源库里管理起来更顺手。先说多表合并。假设业务库里有 12 个月的分表比如orders_202501、orders_202502想抽取到一个汇总表orders_all。最简单的思路是先用一个多表输入 SQL 写出所有分表的 UNION ALL比如SELECT * FROM orders_202501 UNION ALL SELECT * FROM orders_202502 UNION ALL SELECT * FROM orders_202503但这种做法表一多就痛苦。更聪明的做法是利用“表输入”步骤里的动态 SQL 和参数比如把分表名作为变量在作业里循环切换月份然后同一个转换重复执行写入同一张目标表。资源库里把这种通用转换放在公共目录每次只传一个月份变量进去。再说批量遍历日期查数。这个在数据补录和按天抽取时非常常见。我通常会在作业层做循环先用一个“生成时间序列”或自定义的 JavaScript 步骤生成一段日期列表并写入“结果”集合然后在循环内用“结果”的每一行作为参数启动“转换”步骤。在转换里日期放在参数变量中SQL 里写WHERE business_date ?或者用${business_date}占位符。如果不知道怎么在转换里定义参数可以打开转换的属性设置选择“参数”标签页新建一个business_date参数默认值可以填19000101。然后在作业里调用这个转换时在“参数”区域填入对应的变量值。这就是热搜词“kettle 转换里的时间参数在哪里”的答案不在 SQL 编辑器里而是在转换参数配置和调用处。这些场景在文件模式下也能做但放在资源库里后路径统一、作业引用清晰尤其是循环调用的转换不会因为文件路径变了而挂掉。5. 常见问题与排查技巧实录我在用资源库的过程中踩过不少坑这里整理几个出现频率最高的问题也写了对应的排查思路基本都能用。5.1 资源库连接不上、驱动和乱码问题连接资源库时报“无法获取连接”是新手最容易遇到的问题。先检查数据库服务是否启动、IP/端口是否能连通再检查 JDBC 驱动是否存在比如 MySQL 8.x 需要mysql-connector-java或mysql-connector-j的 jar 包放到 Kettle 的lib目录下并重启 Spoon。有些老版本 Kettle 自带的 MySQL 驱动太旧连接新版 MySQL 会直接报 SSL 或时区错误最好换成统一新版驱动。关于乱码如果资源库里存的中文注释或转换名变成问号或乱码需要检查两个方面。一是数据库本身字符集建议建库时直接设置utf8mb4二是连接属性里加上useUnicodetruecharacterEncodingUTF-8。另外 Spoon 的启动参数也可以配置默认字符集Windows 环境可以在 Spoon.bat 里加上-Dfile.encodingUTF-8。实测下来只要这两处保持一致中文乱码基本能消除。5.2 资源库被锁定和并发冲突当多个 Spoon 实例同时连接同一个数据库资源库并且都在编辑同一个对象时可能会出现资源库锁定的提示或者提示“Repository is locked”。这是数据库资源库的正常保护机制防止两个人同时写同一个作业导致数据不一致。解决方法分为几个层级如果是开发人员临时离开忘了释放锁可以在资源库表中找到对应的锁记录并删除不过我不建议直接去删表最好先确认没有其他人正在编辑。另一种情况是用同一个 admin 账号操作多个会话也会造成相互挤占。比较规范的做法是为每个开发人员建独立账号并且遵守“谁锁定谁负责”的约定。至于并发冲突Kettle 在提交时会检查版本号如果发现他人已经更新会弹窗提示冲突这时候尽量以最新的为准手动合并差异。5.3 资源库备份与迁移资源库毕竟是电子数据数据库误删、磁盘损坏都是风险。我对数据库资源库的备份习惯是定期用数据库本身的备份机制比如 MySQL 的mysqldump把整个kettle_repo库导出来。这种方式恢复时最完整。如果想把资源库从一套环境迁移到另一套环境比如从开发迁移到测试除了直接迁移数据库表也可以使用 Kettle 自带的导出功能。在资源库根目录右键选择“全部导出”会生成一个 XML 文件里面包含所有对象和连接元数据。然后在目标资源库里右键“全部导入”就能把整个项目搬到新环境。这里要注意 Kettle 版本之间的差异跨大版本迁移时有些老对象导入新版可能会报兼容性错误所以我一般是升级前先导出备份升级后如果报错再用旧版打开导出一次再在新版导入这个办法虽然笨但能救急。6. 个人体会与后续扩展说到最后聊聊我自己的资源库使用习惯。就个人偏好而言我在本地开发时反而喜欢用文件资源库然后把整个文件夹丢进 Git 仓库里管理这样能享受 commit 记录和分支合并的好处操作起来比数据库资源库开发更轻快。但在测试和生产环境我坚决用数据库资源库而且连接配置尽量走 JNDI账号权限严格控制开发人员默认只读只有运维或项目负责人有写权限。还有一个后续可以扩展的方向是把资源库里的作业交给调度平台去跑。Kettle 自带调度器并不算强更多情况下我们会用统一调度系统来调用。命令行调用资源库里的对象也很方便大概格式是pan.sh -rep dev_repo -user admin -pass admin -trans /订单/ods_order_main.ktr -param:business_date20250101作业则用kitchen.sh来执行。这样在资源库中维护好对象然后通过调度平台传参运行就能把 Kettle 的弱调度短板补上。最后再分享一个小技巧如果你在一个资源库对象上频繁切换不同作业或转换建议把常用对象右键“添加到收藏”。每次打开 Spoon 都能在收藏栏里一键打开不用再去目录里一层层找。资源库用得好感觉就像给 ETL 开发装了一个“版本控制 知识库”单人开发时是一种沉淀多人协作时是一种秩序这大概就是它最大的价值。

相关新闻

FOC不是高级PID:电机磁场定向控制原理与工程实践

FOC不是高级PID:电机磁场定向控制原理与工程实践

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

2026/10/2 16:30:22 阅读更多 →
泰勒公式考研数学全攻略:展开阶数、余项选择与高频题型

泰勒公式考研数学全攻略:展开阶数、余项选择与高频题型

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

2026/10/2 5:18:43 阅读更多 →
海工产品数智孪生构建方案

海工产品数智孪生构建方案

一、海工数智孪生的独特性与挑战海工装备(导管架平台、FPSO、半潜平台、铺缆船、海缆、水下生产系统等)与普通制造装备的数字孪生有本质差异,其核心痛点在于:挑战具体表现环境极端​台风、巨浪、洋流、腐蚀、海生物附着&#xff0…

2026/10/1 20:28:37 阅读更多 →

最新新闻

蛋白质功能位点识别平台构建:从数据到部署的机器学习全流程

蛋白质功能位点识别平台构建:从数据到部署的机器学习全流程

简介:这份PDF文献面向生物信息学、蛋白质功能研究方向的初学者与科研人员,系统讲解如何用支持向量机(SVM)构建蛋白质功能位点识别的通用机器学习平台。内容涵盖非同源序列提取、序列特征编码(基本信息、物化特征、结构…

2026/10/2 22:50:06 阅读更多 →
AI智能体产品开发实战:脚手架选型与复合错误对抗指南

AI智能体产品开发实战:脚手架选型与复合错误对抗指南

1. 从 Grok Bot 一个月造出爆款说起:AI 智能体产品的演化逻辑1.1 一个月造出爆款,到底快在哪里Grok Bot 这个案例最让人坐不住的地方,不是它功能有多逆天,而是从立项到上线只用了一个月。做过 AI 产品的人都知道,这个速…

2026/10/2 22:50:06 阅读更多 →
Agentic AI Infra实战:从单机Demo到生产级Agent服务架构与部署

Agentic AI Infra实战:从单机Demo到生产级Agent服务架构与部署

1. 从云栖2026看Agentic AI Infra到底在解决什么问题1.1 一个真实开发者的困境切入去年下半年我接手了一个企业级智能体项目,需求很明确:让Agent自动完成从工单解析、知识检索、工具调用到结果回写的全链路。听起来不复杂,但真正动手之后才发…

2026/10/2 22:50:06 阅读更多 →
OpenRig:开源自动角色绑定系统,让骨骼绑定不再耗时

OpenRig:开源自动角色绑定系统,让骨骼绑定不再耗时

1. 为什么独立动画师都在聊 OpenRig 做动画的朋友应该都有这种体验:角色骨骼绑定这件事,有点像装修毛坯房——管线、承重、水电都没人替你操心,弄到一半发现骨架方向错了,控制器动不了,权重刷到手抽筋,最后…

2026/10/2 22:50:06 阅读更多 →
openrig模块化机架:用铝型材打造自由装配的设备支架

openrig模块化机架:用铝型材打造自由装配的设备支架

做硬件折腾这么多年,我见过不少号称“模块化”“可重构”的架子方案,但大多数要么是螺丝孔对不上,要么是承重一上就晃,真正能让我拆了又装、反复调整还不觉得烦的很少。看到“openrig”这个词的时候,我第一反应是——这…

2026/10/2 22:50:06 阅读更多 →
128GB统一内存跑Qwen-Image 2.1:Ryzen AI Max+ 395实战详解

128GB统一内存跑Qwen-Image 2.1:Ryzen AI Max+ 395实战详解

1. 这台"大内存怪"凭什么能跑文生图:Ryzen AI Max 395的架构逻辑Ryzen AI Max 395这台128GB统一内存的笔记本,我用了整整三周,干得最多的一件事就是在本地跑Qwen-Image 2.1出图。先说明白这篇东西写给谁:已经入手或打算…

2026/10/2 22:49:05 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/2 6:09:11 阅读更多 →