mql21 / csv-importer
用于在Symfony应用程序中导入CSV文件的工具
Requires
- php: >=7.2.0
This package is not auto-updated.
Last update: 2024-09-29 08:06:33 UTC
README
ORM(对象关系映射)是操作数据库表的有用工具,通过我们通常所说的“实体”来进行,这些实体最终只是类。这样,我们就可以操作那些类,并将它们持久化到我们的数据库中,而无需编写整个SQL代码。
当然,ORM如Doctrine或Propel非常出色,并且具有优势。然而,当您需要处理大量数据集(例如,通过CSV文件导入大量记录)时,有时它们并不十分有用。Doctrine有批量处理机制,但对于非常大的数据集,处理时间仍然可能相当长。
本项目的主要目标是提供一个解决方案,以尽可能短的时间内导入大型CSV文件。目前,本项目已准备好在Symfony(4.3或更高版本)应用程序中使用,但未来可能也会支持其他PHP框架。
安装
要安装此项目,只需使用Composer要求依赖关系
composer require mql21/csv-importer:dev-master
设置CsvImporter
在使用CsvImporter之前,需要对其进行设置。
首先,您需要允许CsvImporterInterface在您的应用程序中被注入为服务,将以下行添加到services.yaml
文件中
mql21\CsvImporter\CsvImporterInterface: ~
现在配置CsvImporter依赖项,添加
mql21\CsvImporter\Builder\CsvImporterMysqlBuilder:
arguments:
$csvMappingFields: "%csv_mapping_fields%"
csv_importer.mysql_builder:
class: mql21\Adapter\CsvImporter\Builder\CsvImporterMysqlBuilder
mql21\CsvImporter\Adapter\CsvImporterMysqlAdapter:
arguments:
$csvImporterMysqlBuilder: "@csv_importer.mysql_builder"
csv_importer.mysql_adapter:
class: mql21\CsvImporter\Adapter\CsvImporterMysqlAdapter
然后,您可以将MySQL适配器简单地自动注入到您的控制器、服务或应用程序中的任何您想要的区域
App\Service\Import\MyImportService:
arguments:
$csvImporter: "@csv_importer.mysql_adapter"
使用CsvImporter
CSV数据需要在services.yaml
中定义,以便导入器知道CSV与数据库之间的映射。为此,您可以在parameters
部分下定义以下配置
parameters:
csv_mapping_fields:
test.person: ## database.destination_table_name
name: ## csv column name
column_name: 'name' ## database table name
required: true ## cannot be empty in csv
surname:
column_name: 'surname'
required: true
所有CSV配置都需要在csv_mapping_fields
范围内定义。
现在您可以在应用程序中注入CsvImporterInterface
并按以下方式执行导入
$csvPath = "some/csv/path/file.csv";
$tableName = "test.person";
$completeMessage = $csvImporter->import($csvPath, $tableName);
提示:确保始终在您的类中注入CsvImporterInterface
以遵循依赖倒置原则。
要查看CsvImporter的使用示例,请访问此仓库:https://github.com/miquelp/Csv-Importer-Example
一些有趣的数据
注意:正如您可能已经注意到的,$csvImporter
并没有明确声明,因为它是通过DI(依赖注入)注入的。
如下图表清楚地显示,使用Doctrine的EntityManager将实体持久化到数据库中可能需要一些时间,特别是如果我们处理相对较大的数据集时。
如您所见,仅写入10000条记录就花费了大约11.5分钟(691.15秒)。
然而,由于CsvImporter使用原生查询写入整个数据,现在所需的时间几乎可以忽略不计。
此外,如果我们尝试导入更大的数据集,我们也可以欣赏到导入时间相当低。
如我们所见,仅需要大约4.7秒即可导入100万条记录。
旁注:这些数据是从安装在16GB RAM的计算机上的本地MySQL数据库收集的。
进一步的工作和为项目做出贡献
任何关于此项目的反馈、修复或贡献都受欢迎。如果您想做出贡献,请随时提交一个pull请求,它将尽快得到检查。
以下是可以立即完成的待办事项列表
- 添加对相关表的支持。CsvImporter的设计目的是将数据写入单个表,因此尚未实现关系。添加某种机制以允许写入多个相关表将非常有意思。
- 添加一些单元测试。
- 将SRP(单一责任原则)应用于
CsvImporterMysqlBuilder.php
,通过将验证方法提取到单独的类中。 - 添加更多字段验证。目前只有两种验证:必填和十进制。任何其他字段验证都将非常受欢迎。
- 使这个库不依赖于任何特定框架。目前它明确地设计为与Symfony一起工作,但添加对其他框架的支持也将非常有意思。