jlucki/spark

Spark 是一个用于 Amazon DynamoDB 的对象文档映射器 (ODM)。

v0.1.2 2022-04-21 21:19 UTC

This package is auto-updated.

Last update: 2024-09-22 23:12:10 UTC


README

GitHub license Code coverage

Spark ODM 目前处于初级阶段,可能不适用于所有应用程序。在部署到任何关键系统之前,请仔细考虑您的使用案例。

体验 DynamoDB

如果您正在寻找一种简单、基于模型的入门方式,那么无需寻找。此 ODM 配备了 Docker 配置文件。下载库并运行 docker-compose up 以启动本地开发环境,包括 DynamoDB 的本地实例。

容器运行后,只需在浏览器中访问 localhost。刷新几次以获取额外的示例博客条目。查看 public/index.php 了解内部情况。

您还可以下载来自 AWS 的 NoSQL Workbench,以便轻松浏览 DynamoDB 数据。安装后,打开工作台,在左侧菜单上单击 操作构建器。单击 + 添加连接,切换到 DynamoDB 本地,给连接命名,端口保留为 8000,然后单击 连接

要求

此库仅适用于 PHP 8.0 及更高版本。

文档

Spark 是一个用于 Amazon DynamoDB 的 PHP ODM 库。

如何使用 Composer 安装

composer require jlucki/spark

如何创建 Spark 连接

如果您使用 Symfony,可以利用 Symfony 的自动装配并在服务构造函数中添加 Spark。

public function __construct(
    private Spark $spark,
) {}

否则,您可以简单地创建一个新的 Spark 类,传递必要的凭据。

$spark = new Spark(
    'latest', // version
    'us-east-1', // region
    'http://dynamodb:8000', // endpoint, use 'regional' for production
    'aws_access_key_id', // your aws access key
    'aws_access_key_secret', // your aws access key secret
);

提示:您可以在本地开发时为 ID 和密钥使用空字符串。

如何创建数据模型

请参阅 Article.php 以获取示例表/项目数据模型。

如何创建全局二级索引

要在表上创建 GSI,请将 GlobalSecondaryIndex 属性添加到属性中。GSI 名称将默认为 AttributeName 的值。或者,您可以通过传递字符串到 GSI 属性 GlobalSecondaryIndex('customName') 来分配自定义名称。

注意:如果 GSI 同时具有 HASHRANGE 键,则必须为 GSI 提供自定义名称,否则这两个键将不会被视为单个 GSI。请参阅以下示例。

默认投影类型是 KEYS_ONLY。要更改投影类型,请将 ProjectionType 属性添加到属性中,并传入以下值之一:ProjectionType::KEYS_ONLYProjectionType::INCLUDEProjectionType::ALL

当使用 ProjectionType::INCLUDE 时,您还必须在属性中添加 NonKeyAttributes 属性,并传入包含您想要投影到索引中的任何属性名称的数组。例如:NonKeyAttributes(['title', 'content'])

#[
    KeyType('HASH'),
    AttributeName('slug'),
    AttributeType('S'),
    GlobalSecondaryIndex('slugIndex'),
    ProjectionType(ProjectionType::ALL),
]
private string $slug;

#[
    KeyType('RANGE'),
    AttributeName('slugDatetime'),
    AttributeType('N'),
    GlobalSecondaryIndex('slugIndex'),
    ProjectionType(ProjectionType::ALL),
]
private DateTime $newSlugDatetime;

如何创建表

$table = $spark->createTable(Article::class);

如何获取或检查表是否存在

$table = $spark->getTable(Article::class);

如何更新表

$result = $spark->updateTable(Article::class);

updateTable() 方法将比较 DynamoDB 提供的描述表模式与本地文件模式,并计算所需的更改。该方法支持:

  • 创建新的 GSI
  • 删除现有的 GSI
  • 更新 GSI,但前提是您还正在更新 ProvisionedThroughput。这是 AWS PHP SDK 的一个明显限制。

提示:您可以在不运行updateTable()方法的情况下向您的模型添加打开属性。这些数据将在您下次添加或更新项目时自动添加到您的表中。

如何删除表格

$result = $spark->deleteTable(Article::class);

警告:这将同时删除表格中的所有项。这一操作无法撤销。

如何将新项放入数据库

$date = new DateTime();

$blog = (new Article())
    ->setType('blog')
    ->setDatetime($date)
    ->setSlug('my-blog-post-' . $date->format('y-m-d-H-i-s'))
    ->setTitle('My Blog Post ' . $date->format('Y-m-d H:i:s'))
    ->setContent('<p>Hello, this is the blog post content.</p>');

// putItem() will return the same object that it persisted to DynamoDB
$blog = $spark->putItem($blog);

如何从数据库获取项

$itemByKey = $spark->getItem(Article::class, [
    'datetime' => $timestamp,
    'type' => 'blog',
]);

如何使用二级索引从数据库获取项

您不能使用getItem()通过二级索引从DynamoDB检索项。这是因为二级索引的哈希键和范围键不是唯一的。但是,您可以使用二级索引查询表,并获取第一个结果。更多详情请见此处

如何更新数据库中的项

$blog->setContent('<p>Updated content!</p>');

try {
    $blog = $spark->updateItem($blog);
} catch (ItemActionFailedException $e) {
    // handle the error
}

if ($blog instanceof Article) {
    // success
}

如何从数据库删除项

try {
    $result = $spark->deleteItem($blog);
} catch (ItemActionFailedException $e) {
    // handle the error
}

如何扫描整个表

$allItems = $spark->scan(Article::class);

如何查询特定项

$from = (new DateTime())->setDate(2010, 1, 1)->getTimestamp();

$blogs = $spark
    ->query(Article::class)
    ->findBy(
        (new Expression())
            ->attribute('datetime')
            ->comparison('>=')
            ->value($from)
    )
    ->findBy(
        (new Expression())
            ->attribute('type')
            ->value('blog')
    )
    ->consistentRead(false)
    ->sortOrder('desc')
    ->getItems();

提示:findBy()仅在表索引属性上工作。您可以使用filterBy(),也可以传递一个Expression对象,以对其他属性进行额外过滤。

提示:您还可以使用getRaw()返回原始的AWS\Result,或使用getHeap()返回一个包含LastEvaluatedKey等所有详细信息且易于使用的对象。

如何使用二级索引查询特定项

$slug = 'my-blog-post-20-12-28-14-46-01';

$foundBySlug = $spark
    ->query(Article::class)
    ->indexName('slug')
    ->findBy(
        (new Expression())
            ->attribute('slug')
            ->value($slug)
    )
    ->getItems();

提示:如果您预期查询结果只有一个项,您可以使用getFirst()代替getItems()。这将返回结果中的第一个ItemInterface对象,如果没有找到任何内容则返回null

如何获取查询项的数量

// getCount() will automatically loop through any additional results
// if the first query result contains a LastEvaluatedKey to get the full count
$totalBlogs = $spark
    ->query(Article::class)
    ->findBy(
        (new Expression())
            ->attribute('datetime')
            ->comparison('>=')
            ->value($from)
    )
    ->findBy(
        (new Expression())
            ->attribute('type')
            ->value('blog')
    )
    ->getCount();

如何直接查询DynamoDbClient

ODM的范围不涵盖AWS SDK for PHP的整个DynamoDB。您可以使用以下方法访问DynamoDbClient及其所有方法,并运行您自己的自定义查询。

$dynamoDbClient = $spark->client();