{"id":21518263,"url":"https://github.com/baopham/laravel-dynamodb","last_synced_at":"2026-01-16T21:57:47.238Z","repository":{"id":998818,"uuid":"37164499","full_name":"baopham/laravel-dynamodb","owner":"baopham","description":"Eloquent syntax for DynamoDB ","archived":false,"fork":false,"pushed_at":"2026-01-15T02:36:16.000Z","size":104493,"stargazers_count":498,"open_issues_count":23,"forks_count":135,"subscribers_count":18,"default_branch":"master","last_synced_at":"2026-01-15T08:43:45.389Z","etag":null,"topics":["aws","dynamodb","laravel","php"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/baopham/dynamodb","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/baopham.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-06-09T23:37:12.000Z","updated_at":"2026-01-15T02:43:42.000Z","dependencies_parsed_at":"2025-05-15T01:09:50.938Z","dependency_job_id":"c136c386-45f1-4672-bbf6-33d7d4cd66f6","html_url":"https://github.com/baopham/laravel-dynamodb","commit_stats":{"total_commits":277,"total_committers":37,"mean_commits":7.486486486486487,"dds":0.296028880866426,"last_synced_commit":"4e35d27b2c5db0f42220b5c6f0e20d83f936909c"},"previous_names":[],"tags_count":78,"template":false,"template_full_name":null,"purl":"pkg:github/baopham/laravel-dynamodb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baopham%2Flaravel-dynamodb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baopham%2Flaravel-dynamodb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baopham%2Flaravel-dynamodb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baopham%2Flaravel-dynamodb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baopham","download_url":"https://codeload.github.com/baopham/laravel-dynamodb/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baopham%2Flaravel-dynamodb/sbom","scorecard":{"id":225466,"data":{"date":"2025-08-11","repo":{"name":"github.com/baopham/laravel-dynamodb","commit":"a6b4e7f90e72aa760fe88f3ee2055e3dc82229ee"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.7,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":8,"reason":"Found 13/16 approved changesets -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 29 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T03:42:47.171Z","repository_id":998818,"created_at":"2025-08-17T03:42:47.171Z","updated_at":"2025-08-17T03:42:47.171Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28484395,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","dynamodb","laravel","php"],"created_at":"2024-11-24T00:51:13.065Z","updated_at":"2026-01-16T21:57:47.223Z","avatar_url":"https://github.com/baopham.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"laravel-dynamodb\n================\n\n[![Latest Stable Version](https://poser.pugx.org/baopham/dynamodb/v/stable)](https://packagist.org/packages/baopham/dynamodb)\n[![Total Downloads](https://poser.pugx.org/baopham/dynamodb/downloads)](https://packagist.org/packages/baopham/dynamodb)\n[![Latest Unstable Version](https://poser.pugx.org/baopham/dynamodb/v/unstable)](https://packagist.org/packages/baopham/dynamodb)\n[![Build Status](https://travis-ci.org/baopham/laravel-dynamodb.svg?branch=master)](https://travis-ci.org/baopham/laravel-dynamodb)\n[![Code Coverage](https://scrutinizer-ci.com/g/baopham/laravel-dynamodb/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/baopham/laravel-dynamodb/?branch=master)\n[![License](https://poser.pugx.org/baopham/dynamodb/license)](https://packagist.org/packages/baopham/dynamodb)\n\nSupports all key types - primary hash key and composite keys.\n\n\u003e For advanced users only. If you're not familiar with Laravel, Laravel Eloquent and DynamoDB, then I suggest that you get familiar with those first. \n\n**Breaking changes in v2: config no longer lives in config/services.php**\n\n* [Install](#install)\n* [Usage](#usage)\n  * [find() and delete()](#find-and-delete) \n  * [Conditions](#conditions)\n  * [all() and first()](#all-and-first)\n  * [Pagination](#pagination)\n  * [update](#update) / [updateAsync()](#updateasync)\n  * [save](#save) / [saveAsync()](#saveasync)\n  * [delete](#delete) / [deleteAsync()](#deleteasync)\n  * [chunk](#chunk)\n  * [limit() and take()](#limit-and-take)\n  * [firstOrFail()](#firstorfail)\n  * [findOrFail()](#findorfail)\n  * [refresh()](#refresh)\n  * [Query scope](#query-scope)\n  * [REMOVE — Deleting Attributes From An Item](#remove--deleting-attributes-from-an-item)\n  * [toSql() Style](#tosql-style)\n  * [Decorate Query](#decorate-query)\n* [Indexes](#indexes)\n* [Composite Keys](#composite-keys)\n* [Query Builder](#query-builder)\n* [Requirements](#requirements)\n* [Migrate from v1 to v2](#migrate-from-v1-to-v2)\n* [FAQ](#faq)\n* [License](LICENSE)\n* [Author and Contributors](#author-and-contributors)\n\nInstall\n------\n\n* Composer install\n    ```bash\n    composer require baopham/dynamodb\n    ```\n \n* Install service provider (\u003c Laravel 5.5):\n\n    ```php\n    // config/app.php\n\n    'providers' =\u003e [\n        ...\n        BaoPham\\DynamoDb\\DynamoDbServiceProvider::class,\n        ...\n    ];\n    ``` \n    \n* Run\n\n    ```php\n    php artisan vendor:publish --provider 'BaoPham\\DynamoDb\\DynamoDbServiceProvider'\n    ``` \n    \n* Update DynamoDb config in [config/dynamodb.php](config/dynamodb.php)\n\n**For Lumen**\n\n* Try [this](https://github.com/laravelista/lumen-vendor-publish) to install the `vendor:publish` command\n  \n* Load configuration file and enable Eloquent support in `bootstrap/app.php`:\n  \n  ```php\n  $app = new Laravel\\Lumen\\Application(\n      realpath(__DIR__.'/../')\n  );\n   \n  // Load dynamodb config file\n  $app-\u003econfigure('dynamodb');\n\n  // Enable Facade support\n  $app-\u003ewithFacades();\n\n  // Enable Eloquent support\n  $app-\u003ewithEloquent();\n  ```\n\n\n\nUsage\n-----\n* Extends your model with `BaoPham\\DynamoDb\\DynamoDbModel`, then you can use Eloquent methods that are supported. The idea here is that you can switch back to Eloquent without changing your queries.  \n* Or if you want to sync your DB table with a DynamoDb table, use trait `BaoPham\\DynamoDb\\ModelTrait`, it will call a `PutItem` after the model is saved.\n* Alternatively, you can use the [query builder](#query-builder) facade to build more complex queries.\n* AWS SDK v3 for PHP uses guzzlehttp promises to allow for asynchronous workflows. Using this package you can run eloquent queries like [delete](#deleteasync), [update](#updateasync), [save](#saveasync) asynchronously on DynamoDb. \n\n### Supported features:\n\n#### find() and delete()\n\n```php\n$model-\u003efind($id, array $columns = []);\n$model-\u003efindMany($ids, array $columns = []);\n$model-\u003edelete();\n$model-\u003edeleteAsync()-\u003ewait();\n```\n\n#### Conditions\n\n```php\n// Using getIterator()\n// If 'key' is the primary key or a global/local index and it is a supported Query condition,\n// will use 'Query', otherwise 'Scan'.\n$model-\u003ewhere('key', 'key value')-\u003eget();\n\n$model-\u003ewhere(['key' =\u003e 'key value']);\n\n// Chainable for 'AND'.\n$model-\u003ewhere('foo', 'bar')\n    -\u003ewhere('foo2', '!=', 'bar2')\n    -\u003eget();\n    \n// Chainable for 'OR'.\n$model-\u003ewhere('foo', 'bar')\n    -\u003eorWhere('foo2', '!=', 'bar2')\n    -\u003eget();\n \n// Other types of conditions\n$model-\u003ewhere('count', '\u003e', 0)-\u003eget();\n$model-\u003ewhere('count', '\u003e=', 0)-\u003eget();\n$model-\u003ewhere('count', '\u003c', 0)-\u003eget();\n$model-\u003ewhere('count', '\u003c=', 0)-\u003eget();\n$model-\u003ewhereIn('count', [0, 100])-\u003eget();\n$model-\u003ewhereNotIn('count', [0, 100])-\u003eget();\n$model-\u003ewhere('count', 'between', [0, 100])-\u003eget();\n$model-\u003ewhere('description', 'begins_with', 'foo')-\u003eget();\n$model-\u003ewhere('description', 'contains', 'foo')-\u003eget();\n$model-\u003ewhere('description', 'not_contains', 'foo')-\u003eget();\n\n// Nested conditions\n$model-\u003ewhere('name', 'foo')\n    -\u003ewhere(function ($query) {\n        $query-\u003ewhere('count', 10)-\u003eorWhere('count', 20);\n    })\n    -\u003eget();\n\n// Nested attributes\n$model-\u003ewhere('nestedMap.foo', 'bar')-\u003ewhere('list[0]', 'baz')-\u003eget();\n```\n\n##### whereNull() and whereNotNull()\n\n\u003e NULL and NOT_NULL only check for the attribute presence not its value being null  \n\u003e See: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html  \n\n```php\n$model-\u003ewhereNull('name');\n$model-\u003ewhereNotNull('name');\n```\n\n#### all() and first()\n\n```php\n// Using scan operator, not too reliable since DynamoDb will only give 1MB total of data.\n$model-\u003eall();\n\n// Basically a scan but with limit of 1 item.\n$model-\u003efirst();\n```\n\n#### Pagination\n\nUnfortunately, offset of how many records to skip does not make sense for DynamoDb.\nInstead, provide the last result of the previous query as the starting point for the next query.  \n\n**Examples:**\n\nFor query such as:\n\n```php\n$query = $model-\u003ewhere('count', 10)-\u003elimit(2);\n$items = $query-\u003eall();\n$last = $items-\u003elast();\n```\n\nTake the last item of this query result as the next \"offset\":\n\n```php\n$nextPage = $query-\u003eafter($last)-\u003elimit(2)-\u003eall();\n// or\n$nextPage = $query-\u003eafterKey($items-\u003elastKey())-\u003elimit(2)-\u003eall();\n// or (for query without index condition only)\n$nextPage = $query-\u003eafterKey($last-\u003egetKeys())-\u003elimit(2)-\u003eall();\n```\n\n#### update()\n\n```php\n// update\n$model-\u003eupdate($attributes);\n```\n\n#### updateAsync()\n\n```php\n// update asynchronously and wait on the promise for completion.\n$model-\u003eupdateAsync($attributes)-\u003ewait();\n```\n\n#### save()\n\n```php\n$model = new Model();\n// Define fillable attributes in your Model class.\n$model-\u003efillableAttr1 = 'foo';\n$model-\u003efillableAttr2 = 'foo';\n// DynamoDb doesn't support incremented Id, so you need to use UUID for the primary key.\n$model-\u003eid = 'de305d54-75b4-431b-adb2-eb6b9e546014';\n$model-\u003esave();\n```\n\n#### saveAsync()\n\nSaving single model asynchronously and waiting on the promise for completion.\n\n```php\n$model = new Model();\n// Define fillable attributes in your Model class.\n$model-\u003efillableAttr1 = 'foo';\n$model-\u003efillableAttr2 = 'bar';\n// DynamoDb doesn't support incremented Id, so you need to use UUID for the primary key.\n$model-\u003eid = 'de305d54-75b4-431b-adb2-eb6b9e546014';\n$model-\u003esaveAsync()-\u003ewait();\n```  \n\nSaving multiple models asynchronously and waiting on all of them simultaneously.  \n\n```php\nfor($i = 0; $i \u003c 10; $i++){\n    $model = new Model();\n    // Define fillable attributes in your Model class.\n    $model-\u003efillableAttr1 = 'foo';\n    $model-\u003efillableAttr2 = 'bar';\n    // DynamoDb doesn't support incremented Id, so you need to use UUID for the primary key.\n    $model-\u003eid = uniqid();\n    // Returns a promise which you can wait on later.\n    $promises[] = $model-\u003esaveAsync();\n}\n\n\\GuzzleHttp\\Promise\\all($promises)-\u003ewait();\n```  \n\n#### delete()\n\n```php\n$model-\u003edelete();\n```\n\n#### deleteAsync()\n\n```php\n$model-\u003edeleteAsync()-\u003ewait();\n```\n\n#### chunk()\n\n```php\n$model-\u003echunk(10, function ($records) {\n    foreach ($records as $record) {\n\n    }\n});\n```\n\n#### limit() and take()\n\n```php\n// Use this with caution unless your limit is small.\n// DynamoDB has a limit of 1MB so if your limit is very big, the results will not be expected.\n$model-\u003ewhere('name', 'foo')-\u003etake(3)-\u003eget();\n```\n\n#### firstOrFail()\n\n```php\n$model-\u003ewhere('name', 'foo')-\u003efirstOrFail();\n// for composite key\n$model-\u003ewhere('id', 'foo')-\u003ewhere('id2', 'bar')-\u003efirstOrFail();\n```\n\n#### findOrFail()\n\n```php\n$model-\u003efindOrFail('foo');\n// for composite key\n$model-\u003efindOrFail(['id' =\u003e 'foo', 'id2' =\u003e 'bar']);\n```\n\n#### refresh()\n\n```php\n$model = Model::first();\n$model-\u003erefresh();\n```\n\n#### Query Scope\n\n```php\nclass Foo extends DynamoDbModel\n{\n    protected static function boot()\n    {\n        parent::boot();\n\n        static::addGlobalScope('count', function (DynamoDbQueryBuilder $builder) {\n            $builder-\u003ewhere('count', '\u003e', 6);\n        });\n    }\n\n    public function scopeCountUnderFour($builder)\n    {\n        return $builder-\u003ewhere('count', '\u003c', 4);\n    }\n\n    public function scopeCountUnder($builder, $count)\n    {\n        return $builder-\u003ewhere('count', '\u003c', $count);\n    }\n}\n\n$foo = new Foo();\n// Global scope will be applied\n$foo-\u003eall();\n// Local scope\n$foo-\u003ewithoutGlobalScopes()-\u003ecountUnderFour()-\u003eget();\n// Dynamic local scope\n$foo-\u003ewithoutGlobalScopes()-\u003ecountUnder(6)-\u003eget();\n```\n\n#### REMOVE — Deleting Attributes From An Item\n\n\u003e See: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.REMOVE\n\n```php\n$model = new Model();\n$model-\u003ewhere('id', 'foo')-\u003eremoveAttribute('name', 'description', 'nested.foo', 'nestedArray[0]');\n\n// Or\nModel::find('foo')-\u003eremoveAttribute('name', 'description', 'nested.foo', 'nestedArray[0]');\n```\n\n\n#### toSql() Style\n\nFor debugging purposes, you can choose to convert to the actual DynamoDb query\n\n```php\n$raw = $model-\u003ewhere('count', '\u003e', 10)-\u003etoDynamoDbQuery();\n// $op is either \"Scan\" or \"Query\"\n$op = $raw-\u003eop;\n// The query body being sent to AWS\n$query = $raw-\u003equery;\n```\n\nwhere `$raw` is an instance of [RawDynamoDbQuery](./src/RawDynamoDbQuery.php)\n\n\n#### Decorate Query\n\nUse `decorate` when you want to enhance the query. For example:\n\nTo set the order of the sort key:\n\n```php\n$items = $model\n    -\u003ewhere('hash', 'hash-value')\n    -\u003ewhere('range', '\u003e', 10)\n    -\u003edecorate(function (RawDynamoDbQuery $raw) {\n        // desc order\n        $raw-\u003equery['ScanIndexForward'] = false;\n    })\n    -\u003eget();\n```\n\nTo force to use \"Query\" instead of \"Scan\" if the library fails to detect the correct operation:\n\n```php\n$items = $model\n    -\u003ewhere('hash', 'hash-value')\n    -\u003edecorate(function (RawDynamoDbQuery $raw) {\n        $raw-\u003eop = 'Query';\n    })\n    -\u003eget();\n```\n\nIndexes\n-----------\nIf your table has indexes, make sure to declare them in your model class like so\n\n```php\n/**\n * Indexes.\n * [\n *     '\u003csimple_index_name\u003e' =\u003e [\n *          'hash' =\u003e '\u003cindex_key\u003e'\n *     ],\n *     '\u003ccomposite_index_name\u003e' =\u003e [\n *          'hash' =\u003e '\u003cindex_hash_key\u003e',\n *          'range' =\u003e '\u003cindex_range_key\u003e'\n *     ],\n * ]\n *\n * @var array\n */\nprotected $dynamoDbIndexKeys = [\n    'count_index' =\u003e [\n        'hash' =\u003e 'count'\n    ],\n];\n```\n\nNote that order of index matters when a key exists in multiple indexes.  \nFor example, we have this\n\n```php\n$model-\u003ewhere('user_id', 123)-\u003ewhere('count', '\u003e', 10)-\u003eget();\n```\n\nwith\n\n```php\nprotected $dynamoDbIndexKeys = [\n    'count_index' =\u003e [\n        'hash' =\u003e 'user_id',\n        'range' =\u003e 'count'\n    ],\n    'user_index' =\u003e [\n        'hash' =\u003e 'user_id',\n    ],\n];\n```\n\nwill use `count_index`.\n\n```php\nprotected $dynamoDbIndexKeys = [\n    'user_index' =\u003e [\n        'hash' =\u003e 'user_id',\n    ],\n    'count_index' =\u003e [\n        'hash' =\u003e 'user_id',\n        'range' =\u003e 'count'\n    ]\n];\n```\n\nwill use `user_index`.\n\n\nMost of the time, you should not have to do anything but if you need to use a specific index, you can specify it like so\n\n```php\n$model-\u003ewhere('user_id', 123)-\u003ewhere('count', '\u003e', 10)-\u003ewithIndex('count_index')-\u003eget();\n```\n\n\nComposite Keys\n--------------\nTo use composite keys with your model:\n\n* Set `$compositeKey` to an array of the attributes names comprising the key, e.g.\n\n```php\nprotected $primaryKey = 'customer_id';\nprotected $compositeKey = ['customer_id', 'agent_id'];\n```\n\n* To find a record with a composite key\n\n```php\n$model-\u003efind(['customer_id' =\u003e 'value1', 'agent_id' =\u003e 'value2']);\n```\n\nQuery Builder\n-------------\n\nUse `DynamoDb` facade to build raw queries\n\n```php\nuse BaoPham\\DynamoDb\\Facades\\DynamoDb;\n\nDynamoDb::table('articles')\n    // call set\u003ckey_name\u003e to build the query body to be sent to AWS\n    -\u003esetFilterExpression('#name = :name')\n    -\u003esetExpressionAttributeNames(['#name' =\u003e 'author_name'])\n    -\u003esetExpressionAttributeValues([':name' =\u003e DynamoDb::marshalValue('Bao')])\n    -\u003eprepare()\n    // the query body will be sent upon calling this.\n    -\u003escan(); // supports any DynamoDbClient methods (e.g. batchWriteItem, batchGetItem, etc.)\n  \nDynamoDb::table('articles')\n    -\u003esetIndexName('author_name')\n    -\u003esetKeyConditionExpression('#name = :name')\n    -\u003esetProjectionExpression('id, author_name')\n    // Can set the attribute mapping one by one instead\n    -\u003esetExpressionAttributeName('#name', 'author_name')\n    -\u003esetExpressionAttributeValue(':name', DynamoDb::marshalValue('Bao'))\n    -\u003eprepare()\n    -\u003equery();\n\nDynamoDb::table('articles')\n    -\u003esetKey(DynamoDb::marshalItem(['id' =\u003e 'ae025ed8']))\n    -\u003esetUpdateExpression('REMOVE #c, #t')\n    -\u003esetExpressionAttributeName('#c', 'comments')\n    -\u003esetExpressionAttributeName('#t', 'tags')\n    -\u003eprepare()\n    -\u003eupdateItem();\n\nDynamoDb::table('articles')\n    -\u003esetKey(DynamoDb::marshalItem(['id' =\u003e 'ae025ed8']))\n    -\u003eprepare()\n    -\u003edeleteItem();\n\nDynamoDb::table('articles')\n    -\u003esetItem(DynamoDb::marshalItem(['id' =\u003e 'ae025ed8', 'author_name' =\u003e 'New Name']))\n    -\u003eprepare()\n    -\u003eputItem();\n\n// Or, instead of ::table()\nDynamoDb::newQuery()\n    -\u003esetTableName('articles')\n\n// Or access the DynamoDbClient instance directly\nDynamoDb::client();\n// pass in the connection name to get a different client instance other than the default.\nDynamoDb::client('test');\n```\n\nThe query builder methods are in the form of `set\u003ckey_name\u003e`, where `\u003ckey_name\u003e` is the key name of the query body to be sent.  \n\nFor example, to build an [`UpdateTable`](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-dynamodb-2012-08-10.html#updatetable) query:\n\n```php\n[\n    'AttributeDefinitions' =\u003e ...,\n    'GlobalSecondaryIndexUpdates' =\u003e ...,\n    'TableName' =\u003e ...\n]\n```\n\nDo:\n\n```php\n$query = DynamoDb::table('articles')\n    -\u003esetAttributeDefinitions(...)\n    -\u003esetGlobalSecondaryIndexUpdates(...);\n```\n\nAnd when ready:\n\n```php\n$query-\u003eprepare()-\u003eupdateTable();\n```\n\nRequirements\n-------------\nLaravel ^5.1\n\n\nMigrate from v1 to v2\n---------------------\n\nFollow these steps:\n\n1. Update your `composer.json` to use v2\n1. Run `composer update`\n1. Run `php artisan vendor:publish`\n1. Move your DynamoDb config in `config/services.php` to the new config file `config/dynamodb.php` as one of the connections\n    1. Move `key`, `secret`, `token` inside `credentials`\n    1. Rename `local_endpoint` to `endpoint`\n    1. Remove `local` field\n\n\nFAQ\n---\nQ: Cannot assign `id` property if its not in the fillable array  \nA: Try [this](https://github.com/baopham/laravel-dynamodb/issues/10)?  \n\n\nQ: How to create migration?  \nA: Please see [this issue](https://github.com/baopham/laravel-dynamodb/issues/90)  \n\n\nQ: How to use with factory?  \nA: Please see [this issue](https://github.com/baopham/laravel-dynamodb/issues/111)  \n\n\nQ: How do I use with Job? Getting a SerializesModels error  \nA: You can either [write your own restoreModel](https://github.com/baopham/laravel-dynamodb/issues/132) or remove the `SerializesModels` trait from your Job.\n\n\nAuthor and Contributors\n-------\n* [Bao Pham](https://github.com/baopham/laravel-dynamodb)\n* [warrick-loyaltycorp](https://github.com/warrick-loyaltycorp)\n* [Alexander Ward](https://github.com/cthos)\n* [Quang Ngo](https://github.com/vanquang9387)\n* [David Higgins](https://github.com/zoul0813)\n* [Damon Williams](https://github.com/footballencarta)\n* [David Palmer](https://github.com/dp88)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaopham%2Flaravel-dynamodb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaopham%2Flaravel-dynamodb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaopham%2Flaravel-dynamodb/lists"}