jpuck / etl
用于提取、转换和加载数据的工具。
Requires
- php: ^7.0
- jpuck/phpdev: ^1.3
- sabre/xml: ^1.4
Requires (Dev)
- phpunit/phpunit: ^5.5
README
这是一个PHP 7类集合,用于在数据源之间进行提取、转换和加载数据。
可以自动将层次结构XML和JSON转换为关系型SQL。支持从文件系统或REST API提取数据文档,然后将其加载到Microsoft SQL Server等数据库管理系统(DBMS)中。
对数据类型、数值基数和唯一自然键候选者进行调研。然后使用此信息创建一个适合插入数据的归一化多表数据库结构。
要求
PHP >= 7.0
安装
此库已在packagist上注册,并可以使用composer轻松安装到您的项目中。
composer require jpuck/etl
入门
有三个基本相关的类组:源提供具有模式的数据。
-
源
源扩展了抽象的
Source
类,并传输Datum
对象。特别是,抽象的DB
类有具体的类实现,如MicrosoftSQLServer
。 -
数据
数据类扩展了
Datum
,必须实现一个有效的解析器,由ParseValidator
满足。它使用Schematizer
从原始数据构造对象,可以通过传递现有的Schema
来覆盖。 -
模式
Schema
是一个具体的类,具有用于强制结构的Validator
。Merger
类用于合并模式以创建超集模式。《DDL》特性和《DB》类一起用于生成包含特定数据库管理系统(DBMS)应实现的具体方法的SQL数据定义语言。
模式化
Schematizer
类用于调查数据结构。它包括节点名称、不同元素分组的计数、子节点之间关系的数值基数,以及包括唯一性在内的值的描述性统计信息。分类上,它识别日期时间、整数和小数数据类型。小数将包括适合SQL的刻度和精度度量。
Schematizer::getPrecision
返回适合SQL DECIMAL(scale,precision)
数据类型的刻度和精度。此函数在通过原始PHP浮点类型传递时丢弃尾随零,但是当作为字符串传递时,精度中会保留尾随零。有关示例,请参阅SchematizerUtilitiesTest::precisionDataProvider
。请注意,在XML
类中,解析值在PHP中表示为字符串,因此尾随零应在精度值中表示。
node name
├── count
│ ├── max
│ │ ├── measure
│ │ └── value
│ └── min
│ ├── measure
│ └── value
├── unique (all values)
├── primaryKey
├── varchar ────┐
│ ├── max │
│ │ ├── measure │
│ │ └── value │
│ └── min │
│ ├── measure │
│ └── value │
├── datetime ├ datatypes
│ ├── max │
│ │ └── value │
│ └── min │
│ └── value │
├── int/decimal │
│ ├── max │
│ │ └── value │
│ └── min │
│ └── value ────┘
├── scale ────┐
│ ├── max │
│ │ ├── measure │
│ │ └── value │
│ └── min │
│ ├── measure │
│ └── value │
├── precision ├ if decimal
│ ├── max │
│ │ ├── measure │
│ │ └── value │
│ └── min │
│ ├── measure │
│ └── value ────┘
├── children
│ ├── distinct (count of children)
│ └── count
│ ├── max
│ │ └── measure
│ └── min
│ └── measure
├── attributes
│ └── ... (excluding count, which must be 1)
└── elements
└── ...
数据库连接
DB
类在构造函数中需要PDO
的实例来连接,但可以通过传递一个null
值仅利用类进行DDL。
SQL数据定义语言
当使用一对多XML节点来表示一对一关系时,Schematizer
会识别这一点,并且一个DDL
类会将它们扁平化为表中的列。如果一个节点具有多个名称或孙节点,则一对一关系将在一个单独的规范化表中保留。创建代理键以维护主/外键引用完整性。
如果Schema
设置了primaryKey
,则该字段将用于DDL生成,而不是代理键。但是,在用DB::insert
使用之前,必须将此Schema
传递给Datum
构造函数。否则,将默认使用代理键,并且如果代理列不存在,将导致插入失败。
保存Schema
生成Schema可能需要很长时间,并且可能需要自定义,例如添加primaryKey
标志或删除要忽略的不想要的字段。以下是一些导出和导入的示例
$xml = file_get_contents("sample.xml"); $xml = new XML($xml); $schema = $xml->schema(); // normal JSON_PRETTY_PRINT echo $schema;
只需简单地回显对象,就可以从控制台将输出重定向到文件
php script.php > myschema.json
使用file_put_contents
将内容写入磁盘。Schema::toJSON
接受所有json_encode
选项。
$string = $schema->toJSON(JSON_UNESCAPED_UNICODE); file_put_contents('myschema.json', $string); // native php array $array = var_export($schema->toArray(), true); $array = "<?php return $array;"; file_put_contents('myschema.php', $array);
通过传递文件名、数组或JSON字符串到构造函数,以相同的方式导入任何这些格式。
$schemas []= new Schema('myschema.php'); $schemas []= new Schema('myschema.json'); $schemas []= new Schema($schema->toArray()); $schemas []= new Schema($schema->toJSON()); $schemas []= new Schema($schema->toJSON(JSON_PRETTY_PRINT)); foreach($schemas as $s){ var_dump($schema == $s); }
通过将Schema
传递给Datum
构造函数来覆盖内部Schematizer
。
$schema = new Schema('myschema.json'); $xml = file_get_contents("sample.xml"); $xml = new XML($xml, $schema);
您也可以通过Source::fetch
传递Schema
覆盖。
$credentials = [ 'url' => 'https://api.example.com', 'username' => 'user', 'password' => 'P@55w0rd', ]; $source = new REST($credentials); $xml = $source->fetch('endpoint', XML::class, new Schema('myschema.json'));
开发
可以通过运行带有或没有--dev
选项(默认启用)的composer来安装开发依赖项。
composer install --dev
测试
测试是为PHPUnit编写的,它作为composer开发依赖项包含在内。要运行整个测试套件,请从shell控制台执行此命令
php vendor/bin/phpunit
您可能还对易于阅读的清单输出感兴趣
php vendor/bin/phpunit --testdox
当在IDE(如Netbeans)中通过断点进行调试时,将运行配置设置为调试可以输出当前测试名称,这很有帮助
php vendor/bin/phpunit --debug
如果您已安装xdebug
扩展,则可以获取代码覆盖率报告。除了控制台文本摘要报告外,还会在coverage
文件夹中生成一个完整的HTML GUI,以便探索。查看此报告的最简单方法是启动开发服务器
php -S localhost:8080 -t coverage/
数据库测试
为了运行数据库测试,您必须创建文件(或符号链接)tests/data/pdos/pdo.php
。这应该简单地返回一个PDO
实例,例如
<?php return (function(){ $hostname = 'sql.example.com'; $database = 'mydb'; $username = 'user'; $password = 'P@55w0rd'; // https://www.microsoft.com/en-us/download/details.aspx?id=50419 $driver = 'ODBC Driver 13 for SQL Server'; $pdo = new PDO("odbc:Driver=$driver; Server=$hostname; Database=$database", $username, $password ); $pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $pdo; })();