agentic_huge_data_base / wiki
页面 Paperless-ngx · 7 导入与导出·DeepWiki 中文全文译文

7 · 导入与导出(Import and Export)

文档归档与消费管道 · 聚焦本章的模块关系、源码依据与实现要点。

项目Paperless-ngx 章节7 状态全文译文 模块文档对象与元数据、系统架构、界面与交互、测试、发布与运维
源码线索
  • src/documents/management/commands/document_exporter.py
  • src/documents/management/commands/document_importer.py
  • src/documents/management/commands/mixins.py
  • src/documents/settings.py
  • src/documents/tests/test_management_exporter.py
  • src/documents/tests/test_management_importer.py
模块标签
  • 文档对象与元数据
  • 系统架构
  • 界面与交互
  • 测试、发布与运维
  • 配置治理

章节正文

导入与导出

导入与导出

相关源文件

本章引用的主要源码文件:

  • src/documents/management/commands/document_exporter.py
  • src/documents/management/commands/document_importer.py
  • src/documents/management/commands/mixins.py
  • src/documents/settings.py
  • src/documents/tests/test_management_exporter.py
  • src/documents/tests/test_management_importer.py

本文档说明了 Paperless-ngx 用于从一个实例导出文档及其元数据,并将其导入到另一个实例的系统。该功能支持数据迁移、备份与恢复操作,以及在独立的 Paperless-ngx 实例之间传输文档集合。

概述

导入/导出系统允许您:

  • 导出所有文档及其元数据(通信方、标签、文档类型等)。
  • 将文档导出到目录或压缩的 zip 文件中。
  • 使用可配置的命名格式来组织导出内容。
  • 通过 CryptMixin 使用加密保护敏感信息。
  • 使用 ijson 进行内存高效的清单解析,将先前导出的数据导入到新的或现有的 Paperless-ngx 实例中。
Paperless-ngx · 概述 · 图 1
Paperless-ngx · 概述 · 图 1

来源:src/documents/management/commands/document_exporter.py:168-177, src/documents/management/commands/document_importer.py:182-192, src/documents/management/commands/mixins.py:23-42

导出系统

导出系统实现为一个 Django 管理命令,它从数据库中提取文档及其元数据,并将其复制到指定的目标位置。

导出命令

导出器命令提供了多种选项来自定义导出过程:

python manage.py document_exporter [选项] <目标目录>
选项描述
--compare-checksums, -c在确定是否导出文件时比较文件校验和 src/documents/management/commands/document_exporter.py:182-192
--compare-json, -cj比较 JSON 文件校验和以确定是否需要更新清单文件 src/documents/management/commands/document_exporter.py:195-205
--delete, -d删除导出目录中不属于当前导出的文件 src/documents/management/commands/document_exporter.py:207-215
--use-filename-format, -f使用 PAPERLESS_FILENAME_FORMAT 在导出目录中存储文件 src/documents/management/commands/document_exporter.py:217-226
--no-archive, -na跳过导出归档文件 src/documents/management/commands/document_exporter.py:228-233
--no-thumbnail, -nt跳过导出缩略图文件 src/documents/management/commands/document_exporter.py:235-240
--use-folder-prefix, -p将文件导出到专用文件夹(归档、原始文件、缩略图) src/documents/management/commands/document_exporter.py:242-250
--split-manifest, -sm将文档信息导出到单独的清单 JSON 文件中 src/documents/management/commands/document_exporter.py:252-261
--zip, -z将文档导出到给定目录中的 zip 文件 src/documents/management/commands/document_exporter.py:263-268
--zip-name, -zn设置导出 zip 文件的名称 src/documents/management/commands/document_exporter.py:270-275
--data-only仅导出数据库条目,不导出文档文件 src/documents/management/commands/document_exporter.py:277-282
--passphrase使用此密码短语加密导出中的敏感数据 src/documents/management/commands/document_exporter.py:284-289

来源:src/documents/management/commands/document_exporter.py:178-293

导出结构

一次导出包含:

  1. 清单文件:包含序列化记录的 manifest.json src/documents/management/commands/document_exporter.py:87-93
  2. 文档文件:原始文档、归档版本和缩略图。
  3. 元数据文件:包含版本信息和加密设置的 metadata.json

StreamingManifestWriter 类用于增量写入 JSON 数组,以避免高内存消耗 src/documents/management/commands/document_exporter.py:87-115

来源:src/documents/management/commands/document_exporter.py:117-136, src/documents/settings.py:1-12

导出过程

当导出命令运行时,它会:

  1. 确定目标路径,并可选地创建一个 ZipFile src/documents/management/commands/document_exporter.py:321-344
  2. 遍历所有相关模型(文档、标签、通信方等) src/documents/management/commands/document_exporter.py:355-393
  3. 使用 serialize_queryset_batched 分块获取和序列化记录 src/documents/management/commands/document_exporter.py:71-84
  4. 使用 copy_file_with_basic_stats 复制文件 src/documents/management/commands/document_exporter.py:536-548
  5. 可选地加密 CryptMixin.CRYPT_FIELDS 中定义的敏感字段(例如,邮件账户密码) src/documents/management/commands/mixins.py:54-71

来源:src/documents/management/commands/document_exporter.py:314-410, src/documents/management/commands/mixins.py:128-133

导入系统

导入系统读取导出的数据并将其恢复到 Paperless-ngx 实例中。它使用 ijson 解析清单,从而能够处理非常大的导出文件,而无需将整个 JSON 加载到内存中 src/documents/management/commands/document_importer.py:62-68

导入命令

导入器命令提供了几个选项:

python manage.py document_importer [选项] <源目录>
选项描述
--data-only仅导入数据库条目,不导入文档文件 src/documents/management/commands/document_importer.py:208-213
--passphrase用于解密导出中敏感字段的密码短语 src/documents/management/commands/document_importer.py:215-220

来源:src/documents/management/commands/document_importer.py:194-222

导入过程

导入过程遵循以下步骤:

  1. 预检查:验证源目录存在且可读 src/documents/management/commands/document_importer.py:294-310
  2. 清单有效性:检查清单中引用的所有文件是否实际存在于导出中 src/documents/management/commands/document_importer.py:312-337
  3. 数据库反序列化_deserialize_record 函数将清单记录转换回 Django 模型实例 src/documents/management/commands/document_importer.py:71-137
  4. 批量创建:使用 bulk_create 将记录分批刷新到数据库以提高性能 src/documents/management/commands/document_importer.py:541-570
  5. 信号处理:在导入期间临时禁用 post_save 等信号,以防止在批量加载期间进行不必要的处理(如文件名重命名) src/documents/management/commands/document_importer.py:465-475

来源:src/documents/management/commands/document_importer.py:225-292, src/documents/management/commands/document_importer.py:532-580

敏感字段解密

如果导出是使用加密创建的:

  1. CryptMixin.load_crypt_params 方法从清单元数据中加载加密参数 src/documents/management/commands/mixins.py:87-100
  2. setup_crypto 使用提供的密码短语和存储的盐值派生密钥 src/documents/management/commands/mixins.py:102-126
  3. 在保存到数据库之前,敏感字段通过 decrypt_string 进行解密 src/documents/management/commands/mixins.py:135-139

来源:src/documents/management/commands/document_importer.py:411-441, src/documents/management/commands/mixins.py:102-139

技术实现

关键类与组件
Paperless-ngx · 关键类与组件 · 图 2
Paperless-ngx · 关键类与组件 · 图 2

来源:src/documents/management/commands/document_exporter.py:87-168, src/documents/management/commands/document_importer.py:182-192, src/documents/management/commands/mixins.py:23-71

数据映射

_deserialize_record 函数在导入期间处理复杂的字段映射:

  • 主键:强制转换为模型所需的正确 Python 类型 src/documents/management/commands/document_importer.py:100-105
  • 多对多关系:主键被收集并在通过 bulk_create 创建主记录后应用 src/documents/management/commands/document_importer.py:111-116
  • 外键:作为整数主键存储在 attname 上(例如,correspondent_id),以避免在反序列化期间进行额外的数据库查找 src/documents/management/commands/document_importer.py:118-126

来源:src/documents/management/commands/document_importer.py:71-137

常见用例

实例间迁移

要将所有数据从一个 Paperless-ngx 实例迁移到另一个实例:

  1. 导出python manage.py document_exporter /path/to/export
  2. 导入python manage.py document_importer /path/to/export
带加密的安全备份

要保护备份中的敏感邮件账户凭据:

python manage.py document_exporter --passphrase "mysecret" /path/to/export

这会触发对 CRYPT_FIELDS 中定义的字段进行 CryptMixin.encrypt_string 操作 src/documents/management/commands/mixins.py:54-71

故障排除

清单验证错误

如果导入失败并显示 CommandError: The manifest file refers to "X" but it does not exist,则 check_manifest_validity 方法发现 JSON 中引用的文件缺失 src/documents/management/commands/document_importer.py:312-337

完整性错误

如果导入到非空数据库,可能会遇到 IntegrityError。导入器会检查现有用户和文档,以在继续之前警告用户 src/documents/management/commands/document_importer.py:235-260

来源:src/documents/management/commands/document_importer.py:312-337, src/documents/tests/test_management_importer.py:30-104