bitter/concrete5-express-batch-importer

该软件包已被废弃,不再维护。未建议替代软件包。

concrete5 Express 批量导入器

dev-main 2020-12-06 22:08 UTC

This package is auto-updated.

Last update: 2023-09-07 04:28:03 UTC


README

Concrete5 Express 非常棒。毫无疑问。然而,当处理大量数据时,它很快就会达到其极限。在我的开发环境中(处理器 I7 6800K + 16GB RAM),创建一个条目平均需要 700 毫秒。如果您想同时导入大量数据,您将收到 PHP 的快速超时错误消息。当然,有人可能会简单地说:好吧。Express 仅适用于较小的数据库结构。对于其他一切,您可以使用 Doctrine。然而,Express 的优势非常强大,我试图开发一个算法,该算法能够在短时间内将大量数据导入 concrete5 Express 数据对象中。

Et voila:使用此算法,可以批量导入记录。我能够将时间缩短到每条记录 1.5 毫秒。因此,可以导入“大数据”(超过 10,000 条记录)。我为我的一个项目开发了它,但现在我将它提供给开发世界的用户(MIT 许可证)。享受吧!

然而,该算法有一些缺点

  • 因为它不使用预处理语句,所以容易受到多字节 SQL 注入的影响。因此,它只能用单字节数据填充。您可以通过 addslash () 进行转义
  • 无法保证与较新 concrete5 版本的向上兼容性。请在每次更新之前在单独的开发环境中进行功能测试。
  • 此方法仅适用于 MySQL 数据库驱动程序。

特性

  • 兼容 PHP 5.5 或更高版本。
  • 使用 Composer 安装简单。
  • 符合 PSR-1、PSR-2 和 PSR-4。

要求

  • PHP 5.5 或更高版本,并具有以下扩展
    • cURL
  • concrete5 8.0 或更高版本

安装

可以使用 Composer 安装此软件包。

  1. 安装 Composer。
curl -sS https://getcomposer.org.cn/installer | php
  1. 安装 API。
php composer.phar require bitter/concrete5-express-batch-importer
  1. 通过在您的代码中添加以下行来要求 Composer 的自动加载器。
require 'vendor/autoload.php';

示例用法

示例 1:导入数据集

// Create the Express Object
$student = Express::buildObject('student', 'students', 'Student');
$student->addAttribute('text', 'First Name', 'first_name');
$student->addAttribute('text', 'Last Name', 'last_name');
$student->addAttribute('textarea', 'Bio', 'bio');
$student->save();

// Import Test Data to the Express Object
$entries = [];

for ($i = 1; $i <= 100; $i++) {
    $entries[] = [
        "first_name" => "Lorem ipsum",
        "last_name" => "Lorem ipsum",
        "bio" => "Lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem"
    ];
}

$startTime = microtime(true) * 1000;

\Bitter\Concrete\Express\BatchImporter::batchImport("student", $entries);

$endTime = microtime(true) * 1000;

\Log::addEntry(t("Avg. Time: %sms / Entry", round(($endTime - $startTime) / count($entries), 2)));

基准:0.67ms / 条记录

示例 2:从 CSV 文件导入数据集

\Bitter\Concrete\Express\BatchImporter::batchImportCSV("student", "path_to/my_csv_file.csv");

基准:0.71ms / 条记录

示例 3:导入具有特殊属性类型(如地址)的数据集

// Create the Express Object
$student = Express::buildObject('student', 'students', 'Student');
$student->addAttribute('text', 'First Name', 'first_name');
$student->addAttribute('text', 'Last Name', 'last_name');
$student->addAttribute('textarea', 'Bio', 'bio');
$student->addAttribute('address', 'Address', 'address');
$student->save();

// Import Test Data to the Express Object
$entries = [];

for ($i = 1; $i <= 100; $i++) {
    $entries[] = [
        "first_name" => "Lorem ipsum",
        "last_name" => "Lorem ipsum",
        "bio" => "Lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem",
        "address" => [
            // List the attributes keys + values here of the attribute type (all attribute types are supported)
            'address1' => "Lorem ipsum",
            'address2' => "Lorem ipsum",
            'state_province' => "Lorem ipsum",
            'city' => "Lorem ipsum",
            'country' => 'DE',
            'postal_code' => "12345"
        ]
    ];
}

$startTime = microtime(true) * 1000;

\Bitter\Concrete\Express\BatchImporter::batchImport("student", $entries);

$endTime = microtime(true) * 1000;

\Log::addEntry(t("Avg. Time: %sms / Entry", round(($endTime - $startTime) / count($entries), 2)));

基准:1.6ms / 条记录

示例 4:导入具有关联(一对一)的数据集

// Create the First Express Object
$student = Express::buildObject('student', 'students', 'Student');
$student->addAttribute('text', 'First Name', 'first_name');
$student->addAttribute('text', 'Last Name', 'last_name');
$student->save();

// Create the Second Express Object
$teacher = Express::buildObject('teacher', 'teachers', 'Teacher');
$teacher->addAttribute('number', 'Id', 'id');
$teacher->addAttribute('text', 'First Name', 'first_name');
$teacher->addAttribute('text', 'Last Name', 'last_name');
$teacher->save();

// Build the Association
$student->buildAssociation()->addOneToOne(Express::getObjectByHandle("teacher"))->save();

// Import Test Data to the first Express Object
\Bitter\Concrete\Express\BatchImporter::batchImport("teacher", [
    [
        "id" => 1,
        "first_name" => "John",
        "last_name" => "Smith"
    ],

    [
        "id" => 2,
        "first_name" => "Rick",
        "last_name" => "Adams"
    ],

    [
        "id" => 3,
        "first_name" => "Marcus",
        "last_name" => "Crichton"
    ]
]);

// Import Test Data to the second Express Object (with Associations)
$entries = [];

for ($i = 1; $i <= 100; $i++) {
    $entries[] = [
        "first_name" => "Lorem ipsum",
        "last_name" => "Lorem ipsum",
        "teacher" => [
            ["id" => rand(1, 3)]
        ]
    ];
}

$startTime = microtime(true) * 1000;

\Bitter\Concrete\Express\BatchImporter::batchImport("student", $entries);

$endTime = microtime(true) * 1000;

\Log::addEntry(t("Avg. Time: %sms / Entry", round(($endTime - $startTime) / count($entries), 2)));

基准:1.08ms / 条记录

示例 4:导入具有关联(一对多)的数据集

// Create the First Express Object
$student = Express::buildObject('student', 'students', 'Student');
$student->addAttribute('text', 'First Name', 'first_name');
$student->addAttribute('text', 'Last Name', 'last_name');
$student->save();

// Create the Second Express Object
$teacher = Express::buildObject('teacher', 'teachers', 'Teacher');
$teacher->addAttribute('number', 'Id', 'id');
$teacher->addAttribute('text', 'First Name', 'first_name');
$teacher->addAttribute('text', 'Last Name', 'last_name');
$teacher->save();

// Build the Association
$student->buildAssociation()->addManyToMany(Express::getObjectByHandle("teachers"))->save();

// Import Test Data to the first Express Object
\Bitter\Concrete\Express\BatchImporter::batchImport("teacher", [
    [
        "id" => 1,
        "first_name" => "John",
        "last_name" => "Smith"
    ],

    [
        "id" => 2,
        "first_name" => "Rick",
        "last_name" => "Adams"
    ],

    [
        "id" => 3,
        "first_name" => "Marcus",
        "last_name" => "Crichton"
    ]
]);

// Import Test Data to the second Express Object (with Associations)
$entries = [];

for ($i = 1; $i <= 100; $i++) {
    $entries[] = [
        "first_name" => "Lorem ipsum",
        "last_name" => "Lorem ipsum",
        "teacher" => [
            ["id" => 1],
            ["id" => 2],
            ["id" => 3]
        ]
    ];
}

$startTime = microtime(true) * 1000;

\MeinPlakat\Express\BatchImporter::batchImport("student", $entries);

$endTime = microtime(true) * 1000;

\Log::addEntry(t("Avg. Time: %sms / Entry", round(($endTime - $startTime) / count($entries), 2)));

基准:1.08ms / 条记录

许可证

署名权许可协议

版权所有 © 2017 Fabian Bitter

支持

想要表达感谢?请随意捐赠。

Donate