Granta MI Scripting Toolkit:Python自动化导出材料数据实践
2026/8/27 10:17:14 网站建设 项目流程

Granta MI Scripting Toolkit 是材料信息管理平台 Granta MI 提供的编程访问入口,在需要批量、重复、定时导出材料数据时,它比界面手工导出要可靠得多。实际项目中,开发者常用它把 Granta MI 里的材料记录、属性、表格数据和关联文件同步到本地、数据仓库或下游系统,也会用它生成定期材料数据快照。这个主题的学习难点不在单个语法,而在连上服务器后如何正确查询记录、读取属性、处理编码、写出文件,并在失败时能快速定位问题。本文围绕使用 Granta MI Scripting Toolkit 导出数据这条主线,从环境准备、最小脚本、细节处理和定时调度几个方面展开,适合负责材料数据管理、需要把 MI 数据接入外部系统的开发者阅读。


1. 先理解 Scripting Toolkit 在材料数据导出中的定位

1.1 从界面导出到脚本导出的变化

Granta MI 自带查询界面和导出功能,适用于临时取数、人工确认、数据量比较小的场景。界面操作虽然直观,但要重复导出同一批材料属性、每周生成一次报告、或把数据交给下游系统时,手工导出很难保证每次的查询条件、显示字段、文件格式完全一致。稍微改一个筛选条件就可能漏掉几十条记录,而且操作过程难以审计。

Scripting Toolkit 的价值在于把“连接、查询、取属性、写文件”变成可保存、可版本管理、可重复执行的代码。脚本一旦写好,每次执行结果都基于同一套逻辑。即使下游系统需要调整字段,也只需要修改代码里的属性列表和输出格式,不需要在界面上重复点击。

1.2 适合用脚本导出的典型场景

在实际落地时,以下几类场景最容易从界面导出迁移到脚本导出:

  • 每月或每周生成材料属性快照,用于项目归档。
  • 把 Granta MI 中的材料数据同步到数据仓库、ERP 或自研选材系统。
  • 在系统迁移或数据治理前,对全量材料数据做一次可审计的导出。
  • 将材料数据接入数据分析流程,例如训练材料性能预测模型。
  • 将 MI 中的表格数据、曲线数据、附件文件批量导出到共享盘或对象存储。

这些场景的共同点是:数据量大、执行频率稳定、输出结果需要被后续程序消费。脚本导出比手工导出更适合自动化,也更容易与现有运维体系结合。

1.3 脚本导出的核心不只是“生成文件”

脚本导出真正的价值是让数据导出结果可重复、可校验、可追溯。很多初级脚本只是把数据打印到屏幕,或者覆盖写一个 CSV,缺少日志、行数统计和异常处理。这样的脚本在测试环境能跑,进入生产后就很难排查:不知道哪一次导出成功,不知道文件里是否包含全部记录,也不知道失败发生在连接阶段还是写入阶段。

因此,一个合格的导出脚本至少要在输出文件中记录三方面信息:导出时间、导出的记录范围、成功记录数。如果出现异常,还应当把异常类型、堆栈和当时的查询条件写入日志。后面的章节会围绕这些要求逐步展开。


2. 准备运行环境:Python、SDK 和连接参数

2.1 环境要求

Granta MI Scripting Toolkit 通常以 Python 包或离线 wheel 文件形式提供。准备环境前,先确认几项基础信息:

项目建议要求说明
Python 版本3.8 及以上不同版本 SDK 对 Python 版本要求不同,以交付文档为准
网络环境能访问 Granta MI 服务器,或内网隔离环境需要确认服务器地址、端口、证书是否可达
安装包wheel 文件或内部软件源如果无法访问外网,优先使用管理员提供的离线包
下游依赖openpyxl、pandas、requests 等按实际输出格式和脚本复杂度选择
账号只读查询账号即可导出场景不建议使用管理员账号

环境准备的关键不是“能装包”,而是“连接参数正确”。如果服务器地址、数据库名、账号权限有一点不匹配,后续所有脚本都会在连接阶段失败。

2.2 安装 Scripting Toolkit

在能够访问内部软件源的环境中,安装命令通常是:

pip install grantami-scripting-toolkit

如果 Granta MI 部署在隔离内网,管理员通常会提供一个 wheel 文件,可以使用本地文件安装:

pip install grantami_scripting_toolkit-xxx-py3-none-any.whl

安装完成后,可以先查看包是否被正确识别:

pip show grantami-scripting-toolkit python -c "import grantami_scripting_toolkit; print(grantami_scripting_toolkit.__version__)"

这里的包名、版本号、导入路径以你实际拿到的安装包为准。不同版本之间的连接方法、类名和参数命名可能有差异,遇到ModuleNotFoundError时,优先检查安装的包名是否写错,而不是怀疑代码逻辑。

2.3 准备服务器地址、数据库和凭据

连接 Granta MI 通常需要以下参数:

参数含义常见示例
serverGranta MI 服务器地址https://mi-server.example.com
database要访问的数据库名称MI_Materials_V5
username登录账号export_user
password登录密码或应用密钥从环境变量读取
timeout请求超时时间120
verify_ssl是否校验服务器证书生产环境为True

不要把密码明文写在脚本里。推荐从环境变量或密钥管理服务读取。连接示例代码如下:

import os # 示例连接代码:实际类名和参数以当前版本 SDK 为准 from grantami_scripting_toolkit import MiClient client = MiClient( server=os.environ["MI_SERVER"], database=os.environ["MI_DATABASE"], username=os.environ["MI_USER"], password=os.environ["MI_PASSWORD"], timeout=120, )

注意:下面代码给出的MiClientquery_recordsfetch_attributes是流程示意。不同版本的 SDK 可能会有不同的类名和方法名,落地前先在你安装的包中打开接口文档或dir(client)确认。


3. 编写第一个导出脚本:从连接服务器到写出 CSV

3.1 导出流程拆解

一个最小可用的导出脚本,可以拆成六个步骤:

  1. 建立会话,连接 Granta MI。
  2. 确定要导出的表和查询条件。
  3. 查询符合条件的记录列表。
  4. 对每条记录读取需要的属性值。
  5. 把属性值组装成 CSV 行数据。
  6. 写出文件,并记录导出统计信息。

这个流程看似简单,但每一步都有容易出错的地方。比如查询条件写错会导致空结果,属性名写错会导致获取不到值,CSV 编码不对会导致 Excel 打开乱码。下面按步骤给出示意实现。

3.2 建立会话并查询记录

建立会话后,第一步是查询记录。以导出名称中包含 “Aluminum” 的材料记录为例:

records = client.query_records( table="Material Data", condition='Name contains "Aluminum"', )

查询条件通常使用 Granta MI 过滤语法。如果条件为空,可以设置condition=None来导出指定表中的全部记录。注意,全部记录导出时数据量可能很大,最好先加limit或在 WHERE 条件里缩小范围。

3.3 读取属性并构造行数据

得到记录列表后,需要读取每条记录的具体属性。材料数据库中的属性通常包括密度、抗拉强度、屈服强度、延伸率等:

header = ["Record ID", "Name", "Density", "Tensile Strength"] rows = [] for record in records: values = client.fetch_attributes( record_id=record.record_id, attributes=["Density", "Tensile Strength"], ) rows.append([ record.record_id, record.name, values.get("Density"), values.get("Tensile Strength"), ])

在实际 SDK 中,fetch_attributes的返回值可能是字典、列表或带属性的对象。关键是明确每个属性对应的数据类型,避免把列表、字典直接写进 CSV。

3.4 写出 CSV 并处理中文字节

写出 CSV 时,推荐使用 Python 标准库csv,并指定 UTF-8 with BOM 编码:

from pathlib import Path import csv out_path = Path("material_export.csv") with out_path.open("w", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerow(header) writer.writerows(rows)

使用utf-8-sig的原因是:Excel 在打开 CSV 文件时,如果文件没有 BOM,默认可能按本地 ANSI 编码解析,中文字段容易出现乱码。utf-8-sig会在文件头写入 BOM,让 Excel 识别为 UTF-8 文件。

3.5 一个最小完整脚本

把以上步骤合并成一个完整脚本:

""" 最小导出脚本示例:连接 Granta MI,查询记录,导出属性到 CSV。 实际类名、方法名、导入路径以你安装的 Scripting Toolkit 版本为准。 """ import csv import os from pathlib import Path from grantami_scripting_toolkit import MiClient # 示例导入 SERVER = os.environ["MI_SERVER"] DATABASE = os.environ["MI_DATABASE"] USERNAME = os.environ["MI_USER"] PASSWORD = os.environ["MI_PASSWORD"] client = MiClient( server=SERVER, database=DATABASE, username=USERNAME, password=PASSWORD, timeout=120, ) records = client.query_records( table="Material Data", condition='Name contains "Aluminum"', ) header = ["Record ID", "Name", "Density", "Tensile Strength"] rows = [] for record in records: values = client.fetch_attributes( record_id=record.record_id, attributes=["Density", "Tensile Strength"], ) rows.append([ record.record_id, record.name, values.get("Density"), values.get("Tensile Strength"), ]) out_path = Path("material_export.csv") with out_path.open("w", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerow(header) writer.writerows(rows) print(f"导出完成: {out_path.resolve()}, 共 {len(rows)} 条记录")

运行脚本前,先确认环境变量已经设置好:

export MI_SERVER="https://mi-server.example.com" export MI_DATABASE="MI_Materials_V5" export MI_USER="export_user" export MI_PASSWORD="your_password"

然后执行:

python export_material_data.py

如果连接成功,脚本会在当前目录生成material_export.csv,并输出导出记录数。


4. 导出数据时必须处理的四个细节

4.1 给记录带一个唯一标识

很多数据库导出工具都有“导出数据没有主键 ID”的问题。DBeaver 导出表数据时,如果只选择了业务字段而漏了主键,后续要用脚本核对哪一行被修改、哪一行需要回写,会非常困难。Granta MI 脚本导出也是同样道理。

导出记录时,至少要携带一个能唯一标识记录的字段。Granta MI 中常见的是记录 ID、History GUID 或记录名称。名称不一定是唯一的,两个不同批次但名称相同的材料可能同时存在,只导出名称会导致后续无法区分记录。

建议在导出表头中增加以下字段:

字段说明
Record ID记录在当前数据库中的唯一编号
Record History GUID记录历史版本标识,适合追踪变更
Name记录名称,便于人工阅读
Last Modified Date最后修改时间,适合增量导出判断

这样导出的数据即使脱离了 Granta MI 界面,也能通过唯一标识定位到原始记录。

4.2 中文字段乱码的根源与处理

中文乱码是导出任务里最常见的问题之一。它的根源通常是“写入编码”与“读取编码”不一致。在 Granta MI 脚本导出场景中,可能出现乱码的位置有三个:

第一,脚本读取数据时,CSV 写出使用了系统默认编码。在 Windows 中文环境下,Python 的默认编码可能是 GBK;在 Linux 环境下可能是 UTF-8。同一个脚本在不同服务器上运行,结果不一样。

第二,CSV 文件本身是 UTF-8 无 BOM,Excel 却按本地 ANSI 解析。这个问题在前面已经提到,解决方案是使用utf-8-sig编码写出。

第三,下游系统按 GB2312 或 GB18030 读取文件,但文件实际是 UTF-8。这种场景需要提前确认下游编码要求。

推荐做法如下:

场景推荐编码说明
文件由 Excel 直接打开utf-8-sig带 BOM,兼容性最好
文件由 Linux 脚本读取utf-8不带 BOM,避免多余字符
老版本中文 Excelgb18030兼容繁体简体,但要注意下游编码约束

如果导出结果用于数据仓库或 BI 工具,优先使用utf-8;如果结果需要业务人员用 Excel 打开,优先使用utf-8-sig

4.3 表格数据和文件类型属性不能简单拍平

Granta MI 中的材料数据不只包含密度、强度这类单值属性,还包含曲线数据、多层表格、图片、PDF 附件等。把这类数据简单“拍平”成一个字段写入 CSV,会丢失数据结构。

表格数据建议按“一主多子”的方式处理:主文件保存记录基础属性,子表单独导出成另一个 CSV 或另一个 Excel Sheet,并通过 Record ID 关联。文件类型属性建议导出为独立文件,同时生成一个元数据清单,记录文件对应哪个 Record ID、哪个属性、保存路径和文件名。

示例输出结构:

export/ metadata.csv records.csv attachments/ record_10001_datasheet.pdf record_10002_curve.png record_10003_test_report.pdf

metadata.csv至少包含 Record ID、属性名、文件名、大小、保存路径。这样附件和主数据在后续处理时可以重新关联。

4.4 大批量导出要控制内存和请求次数

如果一次性查询几千条记录,并把所有记录的所有属性都加载到内存,脚本可能运行到一半就内存溢出或请求超时。处理大量数据时,建议采用分批获取的方式:

  1. 先查询记录 ID 列表,不加载全部属性。
  2. 每 100 条或 200 条记录为一个批次,逐批读取属性。
  3. 每个批次读取后立即写入文件,释放内存。

这种做法的好处是避免服务端单次响应过大,也方便在某个批次失败时重新执行,而不需要重新查询全部记录。


5. 运行验证:不要以“能打开文件”作为通过标准

5.1 文件完整性检查

脚本跑完后,需要验证生成的文件是否完整。常见检查项包括:

  • 文件是否生成,路径是否正确。
  • 文件大小是否在预期范围内。
  • CSV 表头是否和预期字段一致。
  • 空文件是否意味着查询条件或权限有问题。

一个常见的错误是:脚本连接成功,但查询条件写错,导出的 CSV 只有表头没有数据。只看“文件能打开”发现不了这个问题,必须核对记录数。

5.2 行数与关键字段校验

推荐在脚本中加入一个异步或独立的校验步骤:重新读取生成的 CSV,统计行数,并和查询到的记录数对比。也可以手工在 Granta MI 界面执行同样的查询,对比记录数。

一个简单的 Python 校验方法:

import csv expected_count = len(records) with open("material_export.csv", newline="", encoding="utf-8-sig") as f: reader = csv.reader(f) header = next(reader) exported_count = sum(1 for _ in reader) print("表头:", header) print("期望记录数:", expected_count) print("实际记录数:", exported_count)

如果两个数字不一致,优先检查查询条件、分页逻辑和数据修改时间。还需要注意:导出过程中如果其他用户正在修改数据,可能出现导出时记录数和服务端实际数据不一致的情况。

5.3 编码与字段类型检查

编码问题不能等 Excel 打开后才能发现。可以在脚本里加入自动检查:

检查项方法通过标准
CSV 编码openpyxlchardet检测文件编码与预期编码一致
中文字段抽样读取几行,打印字段值没有乱码字符
数字字段抽样校验类型和范围数值格式正确,没有None混入文本
记录数重新读取文件统计与查询结果一致

注意:验证脚本本身也要纳入自动化流程。每次导出后至少执行一次校验,否则导出质量问题要到下游使用数据时才会暴露。


6. 工程化:配置外置、定时任务和日志

6.1 为什么建议把连接信息放到脚本外面

生产环境中的脚本不应该把服务器地址、数据库名、密码写成硬编码。配置外置的目的有三个:不同环境之间切换时不需要改代码;敏感信息不会进入版本库;运维人员可以直接修改配置而不需要接触代码。

常见的配置外置方式包括环境变量、INI/XML 配置文件、配置中心或密钥管理服务。对中小项目而言,XML 配置文件已经足够直观。

6.2 用 XML 文件管理导出任务

下面是一个导出任务配置示例,包含保存路径、调度时间、服务器信息、数据库名称和要导出的表:

<?xml version="1.0" encoding="utf-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" savepath="D:\data_export\材料数据" cron="0 0 2 * * ?"> <server>https://mi-server.example.com</server> <database>MI_Materials_V5</database> <exportTables> <table name="Tensile Properties" format="excel"/> <table name="Physical Properties" format="csv"/> </exportTables> </config>

配置字段说明:

字段含义
savepath导出文件保存目录
cron定时触发表达式,Quartz 风格
server连接服务器地址
database访问的数据库名称
exportTables要导出的数据表列表
table/@format输出格式,可选 csv 或 excel

使用 Python 解析这个配置:

import xml.etree.ElementTree as ET tree = ET.parse("export_config.xml") root = tree.getroot() save_path = root.attrib["savepath"] cron = root.attrib.get("cron", "0 0 2 * * ?") server = root.findtext("server") database = root.findtext("database") tables = [] for table in root.findall("exportTables/table"): tables.append({ "name": table.attrib["name"], "format": table.attrib.get("format", "csv"), })

这种方式适合把调度任务和导出逻辑解耦。运维人员只需要维护 XML 配置,不需要改 Python 代码。

6.3 定时调度方式

导出脚本工程化后,通常会交给调度系统定时执行。不同平台的写法不同:

Windows 计划任务可以使用schtasks命令:

schtasks /create /tn "GrantaExport" /tr "python D:\scripts\export_runner.py" /sc daily /st 02:00

Linux 可以使用 crontab:

0 2 * * * cd /opt/granta-export && python export_runner.py >> logs/export.log 2>&1

如果使用 Quartz 风格表达式,0 0 2 * * ?表示每天凌晨 2 点触发。不同调度框架对字段含义的处理不同,配置前应和调度系统文档核对。

6.4 日志落盘和失败告警

定时任务和手工执行的区别在于:手工执行时人能发现报错,定时任务失败时可能没有任何人察觉。因此必须把日志落到文件,并设置失败通知。

建议每条日志记录以下内容:

2025-06-01 02:00:01 [INFO] 导出任务开始,数据库=MI_Materials_V5 2025-06-01 02:00:15 [INFO] 查询记录完成,records=1280 2025-06-01 02:00:32 [INFO] 写入文件完成,path=D:\data_export\材料数据\records.csv 2025-06-01 02:00:32 [INFO] 校验通过,exported=1280 2025-06-01 02:00:33 [INFO] 导出任务结束

如果出现异常,至少记录异常类型、堆栈、查询条件和当前处理到的记录位置。生产环境可以在此基础上接入邮件、企业微信、钉钉或统一告警平台。


7. 常见坑与排查链路

7.1 高频问题速查

问题现象常见原因检查方式处理建议
连接超时网络不通、服务器端口未放开使用 curl 测试服务器端口确认网络策略、代理设置和超时参数
返回 401/403账号密码错误或账号无权限检查账号和数据库权限使用最小权限只读账号,确认角色
导出结果为空数据库选错、查询条件过严在 Granta MI 界面手工查询对比打印查询条件,确认表名和条件语法
CSV 中文乱码文件编码和读取编码不一致用文本编辑器检查编码写出时使用utf-8-sig,或按下游要求转码
文件写入失败保存目录不存在或权限不足检查目录和权限脚本启动前自动创建目录并检查可写
大批量导出卡死一次请求加载数据过多查看日志和服务端负载分批获取,限制每批记录数
脚本执行时间过长导致会话失效会话超时策略查看会话超时配置在读取前重新认证,或延长会话超时时间
SSL 证书校验失败内网证书不受信任查看证书链测试环境可临时关闭校验,生产环境必须导入 CA 证书

7.2 从现象倒推根因的排查顺序

遇到导出问题时,按以下顺序排查,能避免在错误方向浪费时间:

  1. 检查输入参数。确认 XML 配置、环境变量中的服务器地址、数据库、保存路径是否正确。
  2. 检查网络和证书。服务器能否 ping 通,端口是否开放,证书链是否完整。
  3. 检查账号权限。当前账号是否有查询该表、读取该属性的权限。
  4. 检查查询条件。在 Granta MI 界面手工执行同样条件,对比结果。
  5. 检查代码版本和 SDK 版本。确认脚本里的类名、方法名和当前 SDK 版本一致。
  6. 检查日志和异常。优先看异常类型和堆栈,而不是盲目改代码。
  7. 与服务端管理员确认限制。确认是否存在单次查询数量限制、连接数限制或备份窗口。

7.3 两个排查实例

实例一:Excel 打开 CSV 中文乱码

现象是脚本生成的 CSV 用记事本打开正常,用 Excel 打开乱码。原因是文件没有 BOM,Excel 默认按本地 ANSI 解析。解决方法是把写出编码改为utf-8-sig。如果文件已经生成,可以用文本编辑器另存为带 BOM 的 UTF-8,或转换成gb18030。预防手段是在脚本写出后自动检查文件编码。

实例二:定时任务偶尔导出行数不全

现象是每天凌晨导出的材料数据大部分时间正常,偶尔少几十条。排查时先看日志,发现失败批次的记录数和成功批次有明显差异。进一步检查发现,调度时间和服务端备份窗口重叠,读取时部分记录处于非稳定状态。另一种常见原因是增量导出的时间边界没有固定,导致因时区或调度延迟遗漏记录。处理方法是把调度时间避开备份窗口,并在每次导出前记录本次导出的时间范围,用于下次增量判断。


8. 生产环境最佳实践与扩展方向

8.1 生产环境落地清单

清单项建议
账号权限使用只读账号,不开放写权限
凭据管理密码从环境变量或密钥服务读取,不落入代码库
日志每次导出记录时间、记录数、文件路径、异常信息
校验导出后自动核对记录数和关键字段
告警失败时通过邮件或企业消息通知责任人
调度避开服务端备份窗口,设置超时和重试
文件清理定期清理历史导出文件,避免磁盘写满
版本管理导出脚本进入 Git,配置与代码分离
回滚方案保留上一次导出结果,新版本脚本异常时可快速回退

8.2 通用导出任务的共性经验

Granta MI 脚本导出和 MySQL、Oracle、DBeaver、IDEA Database 中的数据导出有很多共性。无论从哪种系统导出数据,都要关注连接字符集、唯一标识、NULL 值处理和行数校验。比如 DBeaver 导出表数据时漏掉主键,会导致回写和比对困难;Oracle 导出中文乱码通常也是连接字符集和客户端编码不一致造成的。把这些经验沉淀成统一的导出规范,比每次遇到问题再临时排查更有效。

8.3 后续扩展方向

如果导出脚本已经在生产环境稳定运行,下一步可以考虑:

  • 增量导出。利用Last Modified DateRecord History GUID只导出修改过的记录,减少数据量和执行时间。
  • 配置中心化。从 XML 配置迁移到更完整的配置中心,支持在线修改和版本审计。
  • 结果元数据化。导出时同时生成一份 JSON 元数据,描述导出时间、来源库、查询条件、字段映射,方便下游自动解析。
  • 与数据看板集成。把导出的材料数据接入 BI 工具或数据中台,替代人工定期更新报表。

把导出脚本升级成数据订阅服务后,通常会遇到权限、增量计算和调度可靠性三个问题。这也是 Granta MI 数据工程化过程中最值得继续投入的方向。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询