Giter Site home page Giter Site logo

baopham / laravel-dynamodb Goto Github PK

View Code? Open in Web Editor NEW
475.0 21.0 126.0 102.04 MB

Eloquent syntax for DynamoDB

Home Page: https://packagist.org/packages/baopham/dynamodb

License: MIT License

PHP 97.41% JavaScript 2.37% Shell 0.22%
laravel php aws dynamodb

laravel-dynamodb's Introduction

laravel-dynamodb

Latest Stable Version Total Downloads Latest Unstable Version Build Status Code Coverage License

Supports all key types - primary hash key and composite keys.

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.

Breaking changes in v2: config no longer lives in config/services.php

Install

  • Composer install

    composer require baopham/dynamodb
  • Install service provider (< Laravel 5.5):

    // config/app.php
    
    'providers' => [
        ...
        BaoPham\DynamoDb\DynamoDbServiceProvider::class,
        ...
    ];
  • Run

    php artisan vendor:publish --provider 'BaoPham\DynamoDb\DynamoDbServiceProvider'
  • Update DynamoDb config in config/dynamodb.php

For Lumen

  • Try this to install the vendor:publish command

  • Load configuration file and enable Eloquent support in bootstrap/app.php:

    $app = new Laravel\Lumen\Application(
        realpath(__DIR__.'/../')
    );
     
    // Load dynamodb config file
    $app->configure('dynamodb');
    
    // Enable Facade support
    $app->withFacades();
    
    // Enable Eloquent support
    $app->withEloquent();

Usage

  • 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.
  • 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.
  • Alternatively, you can use the query builder facade to build more complex queries.
  • AWS SDK v3 for PHP uses guzzlehttp promises to allow for asynchronous workflows. Using this package you can run eloquent queries like delete, update, save asynchronously on DynamoDb.

Supported features:

find() and delete()

$model->find($id, array $columns = []);
$model->findMany($ids, array $columns = []);
$model->delete();
$model->deleteAsync()->wait();

Conditions

// Using getIterator()
// If 'key' is the primary key or a global/local index and it is a supported Query condition,
// will use 'Query', otherwise 'Scan'.
$model->where('key', 'key value')->get();

$model->where(['key' => 'key value']);

// Chainable for 'AND'.
$model->where('foo', 'bar')
    ->where('foo2', '!=', 'bar2')
    ->get();
    
// Chainable for 'OR'.
$model->where('foo', 'bar')
    ->orWhere('foo2', '!=', 'bar2')
    ->get();
 
// Other types of conditions
$model->where('count', '>', 0)->get();
$model->where('count', '>=', 0)->get();
$model->where('count', '<', 0)->get();
$model->where('count', '<=', 0)->get();
$model->whereIn('count', [0, 100])->get();
$model->whereNotIn('count', [0, 100])->get();
$model->where('count', 'between', [0, 100])->get();
$model->where('description', 'begins_with', 'foo')->get();
$model->where('description', 'contains', 'foo')->get();
$model->where('description', 'not_contains', 'foo')->get();

// Nested conditions
$model->where('name', 'foo')
    ->where(function ($query) {
        $query->where('count', 10)->orWhere('count', 20);
    })
    ->get();

// Nested attributes
$model->where('nestedMap.foo', 'bar')->where('list[0]', 'baz')->get();
whereNull() and whereNotNull()

NULL and NOT_NULL only check for the attribute presence not its value being null
See: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html

$model->whereNull('name');
$model->whereNotNull('name');

all() and first()

// Using scan operator, not too reliable since DynamoDb will only give 1MB total of data.
$model->all();

// Basically a scan but with limit of 1 item.
$model->first();

Pagination

Unfortunately, offset of how many records to skip does not make sense for DynamoDb. Instead, provide the last result of the previous query as the starting point for the next query.

Examples:

For query such as:

$query = $model->where('count', 10)->limit(2);
$items = $query->all();
$last = $items->last();

Take the last item of this query result as the next "offset":

$nextPage = $query->after($last)->limit(2)->all();
// or
$nextPage = $query->afterKey($items->lastKey())->limit(2)->all();
// or (for query without index condition only)
$nextPage = $query->afterKey($last->getKeys())->limit(2)->all();

update()

// update
$model->update($attributes);

updateAsync()

// update asynchronously and wait on the promise for completion.
$model->updateAsync($attributes)->wait();

save()

$model = new Model();
// Define fillable attributes in your Model class.
$model->fillableAttr1 = 'foo';
$model->fillableAttr2 = 'foo';
// DynamoDb doesn't support incremented Id, so you need to use UUID for the primary key.
$model->id = 'de305d54-75b4-431b-adb2-eb6b9e546014';
$model->save();

saveAsync()

Saving single model asynchronously and waiting on the promise for completion.

$model = new Model();
// Define fillable attributes in your Model class.
$model->fillableAttr1 = 'foo';
$model->fillableAttr2 = 'bar';
// DynamoDb doesn't support incremented Id, so you need to use UUID for the primary key.
$model->id = 'de305d54-75b4-431b-adb2-eb6b9e546014';
$model->saveAsync()->wait();

Saving multiple models asynchronously and waiting on all of them simultaneously.

for($i = 0; $i < 10; $i++){
    $model = new Model();
    // Define fillable attributes in your Model class.
    $model->fillableAttr1 = 'foo';
    $model->fillableAttr2 = 'bar';
    // DynamoDb doesn't support incremented Id, so you need to use UUID for the primary key.
    $model->id = uniqid();
    // Returns a promise which you can wait on later.
    $promises[] = $model->saveAsync();
}

\GuzzleHttp\Promise\all($promises)->wait();

delete()

$model->delete();

deleteAsync()

$model->deleteAsync()->wait();

chunk()

$model->chunk(10, function ($records) {
    foreach ($records as $record) {

    }
});

limit() and take()

// Use this with caution unless your limit is small.
// DynamoDB has a limit of 1MB so if your limit is very big, the results will not be expected.
$model->where('name', 'foo')->take(3)->get();

firstOrFail()

$model->where('name', 'foo')->firstOrFail();
// for composite key
$model->where('id', 'foo')->where('id2', 'bar')->firstOrFail();

findOrFail()

$model->findOrFail('foo');
// for composite key
$model->findOrFail(['id' => 'foo', 'id2' => 'bar']);

refresh()

$model = Model::first();
$model->refresh();

Query Scope

class Foo extends DynamoDbModel
{
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('count', function (DynamoDbQueryBuilder $builder) {
            $builder->where('count', '>', 6);
        });
    }

    public function scopeCountUnderFour($builder)
    {
        return $builder->where('count', '<', 4);
    }

    public function scopeCountUnder($builder, $count)
    {
        return $builder->where('count', '<', $count);
    }
}

$foo = new Foo();
// Global scope will be applied
$foo->all();
// Local scope
$foo->withoutGlobalScopes()->countUnderFour()->get();
// Dynamic local scope
$foo->withoutGlobalScopes()->countUnder(6)->get();

REMOVE — Deleting Attributes From An Item

See: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.REMOVE

$model = new Model();
$model->where('id', 'foo')->removeAttribute('name', 'description', 'nested.foo', 'nestedArray[0]');

// Or
Model::find('foo')->removeAttribute('name', 'description', 'nested.foo', 'nestedArray[0]');

toSql() Style

For debugging purposes, you can choose to convert to the actual DynamoDb query

$raw = $model->where('count', '>', 10)->toDynamoDbQuery();
// $op is either "Scan" or "Query"
$op = $raw->op;
// The query body being sent to AWS
$query = $raw->query;

where $raw is an instance of RawDynamoDbQuery

Decorate Query

Use decorate when you want to enhance the query. For example:

To set the order of the sort key:

$items = $model
    ->where('hash', 'hash-value')
    ->where('range', '>', 10)
    ->decorate(function (RawDynamoDbQuery $raw) {
        // desc order
        $raw->query['ScanIndexForward'] = false;
    })
    ->get();

To force to use "Query" instead of "Scan" if the library fails to detect the correct operation:

$items = $model
    ->where('hash', 'hash-value')
    ->decorate(function (RawDynamoDbQuery $raw) {
        $raw->op = 'Query';
    })
    ->get();

Indexes

If your table has indexes, make sure to declare them in your model class like so

/**
 * Indexes.
 * [
 *     '<simple_index_name>' => [
 *          'hash' => '<index_key>'
 *     ],
 *     '<composite_index_name>' => [
 *          'hash' => '<index_hash_key>',
 *          'range' => '<index_range_key>'
 *     ],
 * ]
 *
 * @var array
 */
protected $dynamoDbIndexKeys = [
    'count_index' => [
        'hash' => 'count'
    ],
];

Note that order of index matters when a key exists in multiple indexes.
For example, we have this

$model->where('user_id', 123)->where('count', '>', 10)->get();

with

protected $dynamoDbIndexKeys = [
    'count_index' => [
        'hash' => 'user_id',
        'range' => 'count'
    ],
    'user_index' => [
        'hash' => 'user_id',
    ],
];

will use count_index.

protected $dynamoDbIndexKeys = [
    'user_index' => [
        'hash' => 'user_id',
    ],
    'count_index' => [
        'hash' => 'user_id',
        'range' => 'count'
    ]
];

will use user_index.

Most 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

$model->where('user_id', 123)->where('count', '>', 10)->withIndex('count_index')->get();

Composite Keys

To use composite keys with your model:

  • Set $compositeKey to an array of the attributes names comprising the key, e.g.
protected $primaryKey = 'customer_id';
protected $compositeKey = ['customer_id', 'agent_id'];
  • To find a record with a composite key
$model->find(['customer_id' => 'value1', 'agent_id' => 'value2']);

Query Builder

Use DynamoDb facade to build raw queries

use BaoPham\DynamoDb\Facades\DynamoDb;

DynamoDb::table('articles')
    // call set<key_name> to build the query body to be sent to AWS
    ->setFilterExpression('#name = :name')
    ->setExpressionAttributeNames(['#name' => 'author_name'])
    ->setExpressionAttributeValues([':name' => DynamoDb::marshalValue('Bao')])
    ->prepare()
    // the query body will be sent upon calling this.
    ->scan(); // supports any DynamoDbClient methods (e.g. batchWriteItem, batchGetItem, etc.)
  
DynamoDb::table('articles')
    ->setIndexName('author_name')
    ->setKeyConditionExpression('#name = :name')
    ->setProjectionExpression('id, author_name')
    // Can set the attribute mapping one by one instead
    ->setExpressionAttributeName('#name', 'author_name')
    ->setExpressionAttributeValue(':name', DynamoDb::marshalValue('Bao'))
    ->prepare()
    ->query();

DynamoDb::table('articles')
    ->setKey(DynamoDb::marshalItem(['id' => 'ae025ed8']))
    ->setUpdateExpression('REMOVE #c, #t')
    ->setExpressionAttributeName('#c', 'comments')
    ->setExpressionAttributeName('#t', 'tags')
    ->prepare()
    ->updateItem();

DynamoDb::table('articles')
    ->setKey(DynamoDb::marshalItem(['id' => 'ae025ed8']))
    ->prepare()
    ->deleteItem();

DynamoDb::table('articles')
    ->setItem(DynamoDb::marshalItem(['id' => 'ae025ed8', 'author_name' => 'New Name']))
    ->prepare()
    ->putItem();

// Or, instead of ::table()
DynamoDb::newQuery()
    ->setTableName('articles')

// Or access the DynamoDbClient instance directly
DynamoDb::client();
// pass in the connection name to get a different client instance other than the default.
DynamoDb::client('test');

The query builder methods are in the form of set<key_name>, where <key_name> is the key name of the query body to be sent.

For example, to build an UpdateTable query:

[
    'AttributeDefinitions' => ...,
    'GlobalSecondaryIndexUpdates' => ...,
    'TableName' => ...
]

Do:

$query = DynamoDb::table('articles')
    ->setAttributeDefinitions(...)
    ->setGlobalSecondaryIndexUpdates(...);

And when ready:

$query->prepare()->updateTable();

Requirements

Laravel ^5.1

Migrate from v1 to v2

Follow these steps:

  1. Update your composer.json to use v2
  2. Run composer update
  3. Run php artisan vendor:publish
  4. Move your DynamoDb config in config/services.php to the new config file config/dynamodb.php as one of the connections
    1. Move key, secret, token inside credentials
    2. Rename local_endpoint to endpoint
    3. Remove local field

FAQ

Q: Cannot assign id property if its not in the fillable array
A: Try this?

Q: How to create migration?
A: Please see this issue

Q: How to use with factory?
A: Please see this issue

Q: How do I use with Job? Getting a SerializesModels error
A: You can either write your own restoreModel or remove the SerializesModels trait from your Job.

Author and Contributors

laravel-dynamodb's People

Contributors

alfredkoncsag avatar baopham avatar crhg avatar cthos avatar dp88 avatar dylan-dpc avatar fd-automox avatar footballencarta avatar frank-amsterdam avatar gchauqui-bondacom avatar guspio avatar jackpriceburns avatar laravel-shift avatar madeitbelgium avatar michaelshaffer37 avatar mlcollins10 avatar nelson6e65 avatar odiaseo avatar palpalani avatar pellaras avatar royhp avatar sahilsharma011 avatar stancl avatar teeedwards avatar thebatclaudio avatar tudor2004 avatar vanquang9387 avatar warrick-loyaltycorp avatar xabbuh avatar zoul0813 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-dynamodb's Issues

Laravel Auth and DB Relations

Just started using this package. Could you advise on how to use this package with Laravel Authentication and Authorization.

Additionally, how do I use Laravel Relations and Eager Loading with this package?

Model Events not firing?

I created an observer for one of my models, and none of the event methods are being called. I've also setup a standard event listener and that does not get called either.

// AppServiceProvider.php
public function boot() {
  // ...
  Model::observe(Listeners\ModelObserver::class);
  // ...
}

// ModelObserver.php
class ModelObserver {
  public function saved(Model $model) {
    // ...
  }
}

// executed code
$models = App\Model::all();
foreach($models as $model) {
  $model->save();
}

I've tracked this down to the DynamoDbModel's save method.

    public function save(array $options = [])
    {
        if(!$this->getKey()) {
            $this->fireModelEvent('creating');
        }
        return $this->newQuery()->save();
    }

Which I believe should look something more like this:

    public function save(array $options = [])
    {
        $create = !$this->exists;
        if ($create) {
            if($this->fireModelEvent('creating')  === false) return false;
        } else {
            if($this->fireModelEvent('updating') === false) return false;
        }

        if($this->fireModelEvent('saving') === false) return false;

        $saved = $this->newQuery()->save();

        if($saved) {
            if ($create) {
                $this->fireModelEvent('created');
            } else {
                $this->fireModelEvent('updated');
            }
            $this->finishSave($options);
        }
        return $saved;
    }

This fires creating, updating, saving, created, updated and saved events correctly, and also calls finishSave($options) at the end which then calls syncOriginal()

Need Sql table

Hello,

Why is not explained that in order to work the paginate it needs the table at MySql?? I've been having lot of struggle with make it work for that reason.

And your dynamo local box is not working for me neither.
java -Djava.library.path=./DynamoDBLocal_lib -jar vendor/baopham/dynamodb/dynamodb_local/DynamoDBLocal.jar --port 3000 -inMemory

AWS Error

Hey there,

I am trying to save (putItem) and item however I am not sure how to specify the type of value using the package.

This is my code:

    $model = new \App\Models\dynamoModel();
    $model->id = '2123123123123';
    $model->name = 'Tony';
    $model->save(); 

I am getting the following error:

DynamoDbException in WrappedHttpHandler.php line 152:
Error executing "PutItem" on "https://dynamodb.us-east-1.amazonaws.com"; AWS HTTP error: Client error: 400 ValidationException (client): One or more parameter values were invalid: Type mismatch for key id expected: N actual: S - {"__type":"com.amazon.coral.validate#ValidationException","message":"One or more parameter values were invalid: Type mismatch for key id expected: N actual: S"}

Thanks!

support timestamps

Timestamps are managed explicitly by Eloquent, and don't require any support from the backend database.

We can add something like this to the save(...) call, to have self::CREATED_AT and self::UPDATED_AT columns set to the current timestamp as necessary.

        if ($this->usesTimestamps()) {
            $this->updateTimestamps();
        }

This would go directly after the saving/creating/updating events are fired, and before the $saved = $this->newQuery()->save(); is called.

We can then manage created/updated values of our DynamoDb items, and if we want to use custom property names, we can just change the const CREATED_AT = 'created_at' value in our models.

Instances of Aws\DynamoDb\DynamoDbClient cannot be serialized

When trying to cache collections, this error appears.

Seems this simple fix solves the problem. Though it may need to be evaluated a bit to make sure it recreates a proper DynamoDbModel instance when unserialized. $this->toArray() may also be the wrong way to access the data, the smallest possible data set should be returned to reduce memory requirements for caching layers.

DynamoDbModel.php

<?php

namespace BaoPham\DynamoDb;

use Exception;
use DateTime;
use Serializable;
use Illuminate\Database\Eloquent\Model;

/**
 * Class DynamoDbModel.
 */
abstract class DynamoDbModel extends Model implements Serializable
{
    // clipped rest of class

    public function serialize() {
        return serialize($this->toArray());
    }

    public function unserialize($data) {
        $arr = unserialize($data);
        $this->fill($arr);
        $this->setUnfillableAttributes($arr);
        $this->syncOriginal();
    }

}

How to declare $dynamoDbIndexKeys

Hi, I have this table:

            'AttributeDefinitions'  => [
                ['AttributeName' => 'parent_id', 'AttributeType' => 'S'],
                ['AttributeName' => 'id', 'AttributeType' => 'S'],
                ['AttributeName' => 'sort_no', 'AttributeType' => 'N']
            ],
            'KeySchema'             => [
                ['AttributeName' => 'parent_id', 'KeyType' => 'HASH'],
                ['AttributeName' => 'id', 'KeyType' => 'RANGE'],
            ],
            'LocalSecondaryIndexes' => [
                [
                    'IndexName'  => 'idx_category_sort',
                    'KeySchema'  => [
                        ['AttributeName' => 'parent_id', 'KeyType' => 'HASH'],
                        ['AttributeName' => 'sort_no', 'KeyType' => 'RANGE']
                    ],
                    'Projection' => [
                        'ProjectionType'   => 'INCLUDE',
                        'NonKeyAttributes' => ['name', 'topics_count', 'state']
                    ]
                ]
            ],

How can I declare $dynamoDbIndexKeys with this table?
Thank you.

EC2 IAM Role

Hi,
how do i use this with EC2 IAM role instead of access keys? kindly help. thank you

Call to a member function getClient() on null

This may be related to all the recent changes, ... and maybe I didn't update something I should have ...

composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)                      
Nothing to install or update
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize
                                                           
  [Symfony\Component\Debug\Exception\FatalThrowableError]  
  Call to a member function getClient() on null            
                                                           

Script php artisan optimize handling the post-update-cmd event returned with error code 1

This seems to be related to calling $this->dynamoDb->getClient() inside of DynamoDbModel ... looks like this is a recent change. I believe I was previously using 4.0 or 4.1 - are there any config changes needed to support 5.0?

Readme error

Missing a comma after the local_endpoint URL in service.php code snippet

REQUEST: Support local endpoint for testing

Hi there,

Only when the app is running in unit test mode does it support the 'endpoint' argument when creating a new client.

It would be nice to be able to use the local DB for local testing as without requiring an actual key/secret.

Thanks

Cant Insert

Hi, i cant insert or query from DynamoDB.

Here is my controller code:

<?php

namespace App\Http\Controllers;

use App\Jobs\ApiLog;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\DynamoDBLog;

class LogController extends Controller
{
    //
    public function index()
    {
        $model              = new DynamoDBLog();
        $model->id          = str_random(16);
        $model->uri         = 'api.blabla.com/endpoint';
        $model->response    = 'response';
        $model->created     = 'today';

        $model->save();

        return $model;
    }

    public function showList()
    {
        $model = DynamoDBLog::all();

        return $model;
    }

}

and the model:

<?php

namespace App;

use BaoPham\DynamoDb\DynamoDbModel;

class DynamoDBLog extends DynamoDbModel
{
    //
    protected $table        = 'logs';
    protected $fillable     = ['id', 'uri', 'response', 'created'];
}

I've setup my credentials and running dynamoDb locally, what could be wrong?

'exists' is not set after 'save'

Eloquent sets $this->exists = true; after saving a new item, as well as "$this->wasRecentlyCreated = true;" (not sure what that is used for though).

DynamoDB Local error executing scan

I have a model named User and a DynamoDB Local table named users . On dynamodb local shell the table is there(and the "rows" are there too) but on app all i get is the following:

Error executing "Scan" on "http://localhost:3000"; AWS HTTP error: Client error: POST http://localhost:3000 resulted in a 400 Bad Request response:
{"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException","message":"Cannot do operations on a non-existent (truncated...)
ResourceNotFoundException (client): Cannot do operations on a non-existent table - {"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException","message":"Cannot do operations on a non-existent table"}

I need to be retrieved only table values but result contain objects itself.

##Dynamodb local database##

Table

var params = {
TableName: 'docpanel-auditlogs-trials',
KeySchema: [
{
AttributeName: '_id',
KeyType: 'HASH',
}
],
AttributeDefinitions: [
{
AttributeName: '_id',
AttributeType: 'S',
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 100,
WriteCapacityUnits: 100,
}
};
dynamodb.createTable(params, function(err, data) {
if (err) ppJson(err);
else ppJson(data);

});

###Inserted values are###

var params = {
TableName: 'docpanel-auditlogs-trials',
Item: {
"_id":"1256H-2334A-dsrt1",
"user_id":"NULL",
"case_id":"NULL",
"action_type": "Login",
"log_type":"NULL",
"invoke_time": "2017-07-19 10:52:18",
"actions": {
"case_id": "101",
"status": "read"
}
}
};
docClient.put(params, function(err, data) {
if (err) ppJson(err);
else ppJson(data);
});

Model

namespace App;

class Dynamodb extends \BaoPham\DynamoDb\DynamoDbModel
{

protected $fillable = ['_id', 'case_id', 'count','action_type','log_type','invoke_time'];

protected $table = 'docpanel-auditlogs-trials';

public $timestamps = true;

}

Controller
use App\Dynamodb;

class DynamodbController extends Controller
{

public function get(Request $request) {

    $dynamodbObj=new Dynamodb();
   $result=$dynamodbObj->where('_id', '1256H-2334A-dsrt1')->get();
   print_r($result);
   exit;
}

}

Results contain the all the objects. I need to retrieved table values.

Laravel/Lumen 5.3 Support

Cannot use this with Laravel/Lumen 5.3

composer require baopham/dynamodb
Using version ^0.3.0 for baopham/dynamodb
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for baopham/dynamodb ^0.3.0 -> satisfiable by baopham/dynamodb[0.3.0].
    - Conclusion: remove paragonie/random_compat v2.0.2
    - Conclusion: don't install paragonie/random_compat v2.0.2
    - baopham/dynamodb 0.3.0 requires paragonie/random_compat ^1.1 -> satisfiable by paragonie/random_compat[1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.2.x-dev, v1.2.0, v1.2.1, v1.2.2, v1.2.3, v1.3.0, v1.3.1, v1.4.0, v1.4.1, v1.x-dev].
    - Can only install one of: paragonie/random_compat[v1.4.0, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.4.1, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.x-dev, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.1.0, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.1.1, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.1.2, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.1.3, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.1.4, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.1.5, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.1.6, v2.0.2].
    - Can only install one of: paragonie/random_compat[1.2.x-dev, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.2.0, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.2.1, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.2.2, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.2.3, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.3.0, v2.0.2].
    - Can only install one of: paragonie/random_compat[v1.3.1, v2.0.2].
    - Installation request for paragonie/random_compat (locked at v2.0.2) -> satisfiable by paragonie/random_compat[v2.0.2].


Installation failed, reverting ./composer.json to its original content.

Adding PR - #28

Cant get data - always return NULL

I have codes in my controller like this

use App\DynamoLogsPayment;

class LogController extends Controller
{
    public function index()
    {
        $data = DynamoLogsPayment::all();
        foreach ($data as $val) {
            dd($val->id); // return NULL
        };

        DynamoLogsPayment::chunk(100, function ($logs) {
            foreach ($logs as $log) {
                echo var_dump($log->id) . ' <br><br>'; // return NULL
            };
        });

    }
}

and here is my model

namespace App;

use BaoPham\DynamoDb\DynamoDbModel;

class DynamoLogsPayment extends DynamoDbModel
{
    //
    protected $table;
    protected $fillable = ['id', 'uri', 'type', 'provider', 'channel', 'info', 'data_in', 'data_out', 'time', 'time_wib'];

    public function __construct() {
        parent::__construct();

        $this->table = env('DYNAMODB_PREFIX') . 'logs_payment';
    }
}

and I am always getting NULL, could somebody help me. Thanks

DateTime::ISO8601 isn't ISO8601 compatible

Just discovered that DateTime::ISO8601 isn't compatible with the ISO8601 standard, PHP Docs state that you should use DateTime::ATOM to be compatible.

DateTime::ATOM
DATE_ATOM
Atom (example: 2005-08-15T15:52:01+00:00)

DateTime::ISO8601
DATE_ISO8601
ISO-8601 (example: 2005-08-15T15:52:01+0000)
Note: This format is not compatible with ISO-8601, but is left this way for backward compatibility reasons. Use DateTime::ATOM or DATE_ATOM for compatibility with ISO-8601 instead.

http://www.php.net/manual/en/class.datetime.php

The difference appears to be in how the TZ Offset at the end is formatted (0000 vs 00:00).

An example of DynamoDB

hi, i am a new laravel and aws user
i had finished the steps before [Usages] in documentation
but i cant understand how to use it
Can anyone give an example of what code should apply and where?

Thanks!

Using BaoPham\DynamoDb\ModelTrait causes an error

Hi, this trait is causing an error since is trying to use a method that is not defined in the Model class getTableName() it should use getTable() as is used in the rest of the library.

FatalThrowableError
Call to undefined method BaoPham\DynamoDb\DynamoDbQueryBuilder::getTableName()

I don't find any definition of that function in the library neither in Laravel framework so I assume is a mistake in the name.

Thanks @baopham

Using same instance of the model

When we call a query e.g.

$count = Analytics::where('columnA', '524352')
                    ->where('columnB', $source)
                    ->where('columnC', '=', $date)
                    ->get();

then proceed to call

$campaign_sources = Analytics::where('columnA', '524352')->get();

the second query fails with an empty array. If the previous query returned empty results any subsequent calls to Analytics:: will fail with an empty result. It is not created a new model class,.

If i do this:

new Analytics();
$campaign_sources = Analytics::where('columnA', '524352')->get();

the above works as I manually triggered a new Analytics before the second query.

take()/limit() not available?

Looks like the Query Builder's "take" and "limit" methods are not available, preventing you from limiting the results returned.

// Should return up to 50 results, no more
$results = Model::take(50)->get();

The "getAll" method has a $limit parameter, but this also does not appear to work due to the "use_iterator" parameter being defaulted to true.

Changing the default to false for $user_iterator, and adding the following code to the DynamoDbBuilder class seems to allow "take()/limit()" to work as expected.

    /**
     * @var int
     */
    protected $limit = -1;

    /**
     * Alias to set the "limit" value of the query.
     *
     * @param  int  $value
     * @return \Illuminate\Database\Query\Builder|static
     */
    public function take($value)
    {
        return $this->limit($value);
    }

    /**
     * Set the "limit" value of the query.
     *
     * @param  int  $value
     * @return $this
     */
    public function limit($value) {
        $this->limit = $value;
        return $this;
    }

    protected function getAll($columns = [], $limit = -1, $use_iterator = true)
    {
        if($limit === -1) $limit = $this->limit; // set the limit to the 
        // clipped remaining method code as it's unchanged
    }

no query scope support?

It looks like query scopes are not supported. I'm looking into this now, and may have a PR to add support for query scopes.

laravel 5.3 error... anyone know what the problem? using localhost

Error 1:
ClientException in RequestException.php line 111:
Client error: POST https://dynamodb.ap-southeast-1.amazonaws.com resulted in a 400 Bad Request response:
{"__type":"com.amazon.coral.service#AccessDeniedException","Message":"User: arn:aws:iam::893977949585:user/abc is not a (truncated...)

Error 2:
DynamoDbException in WrappedHttpHandler.php line 192:
Error executing "Scan" on "https://dynamodb.ap-southeast-1.amazonaws.com"; AWS HTTP error: Client error: POST https://dynamodb.ap-southeast-1.amazonaws.com resulted in a 400 Bad Request response:
{"__type":"com.amazon.coral.service#AccessDeniedException","Message":"User: arn:aws:iam::893977949585:user/abc is not a (truncated...)

Model

route
Route::get('dynamodb',function(){
$user = \App\DynamoDb::all();
print_r($user);

.env
DYNAMODB_KEY=AKIA...
DYNAMODB_SECRET=Ixnbox....
DYNAMODB_REGION=ap-southeast-1

Table Relationship

Hello, I have an question
I want to display all posts in a page

Here is my dynamodb

users Table: user_id | name | password
posts Table: id | body | user_id

user_id for me to link, so one user has many posts
I just simply use Auth::user()->user_id to get user id and request body to create a new post item

but how to foreach the following?

name(from users) : body(from posts)

DynamoDbException in WrappedHttpHandler error

Hello, Im trying to access/write messages in a Dynamodb table, but all Im getting is this when I try to get:

DynamoDbException in WrappedHttpHandler.php line 192: Error executing "GetItem" on "https://dynamodb.us-east-1.amazonaws.com"; AWS HTTP error: Client error: POST https://dynamodb.us-east-1.amazonaws.com resulted in a 400 Bad Request response: {"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema" (truncated...) ValidationException (client): The provided key element does not match the schema - {"__type":"com.amazon.coral.validate#ValidationException","message":"The provided key element does not match the schema"}

Im using a user with the necessary permissions Can somebody please help me thanks

Query Supported Operators

Currently, laravel-dynamodb only supports EQ for key condition.
But, supported operators are varied by Partition Key and Sort Key for Query.
Partition Key operator

EQ

Sort Key operators

EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN

Ref
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.KeyConditions.html

If I have this protected $compositeKey = ['parent_id', 'id'];
When execute $this->where('parent_id', 100)->where('id', '>', 100)->get(); will give this condition: parent_id EQ 100 AND id EQ 100. Any operators for id (sort key) will become EQ;

[Question] Working with Realtionships

Using this package is it possible to use the Laravel relationships?

For example I have the following structure in Dynamo

Table Name Hash Key Range Key
Forum id
Thread id forum

So a thread belongs to a forum, is there a way to hook this up using this package?

isDirty() after retrieving models

Models appear to be dirty after retrieving them.

When using a standard Eloquent model, isDirty() returns false after retrieving it ...however, DynamoDbModel instances appear to be dirty after retrieving them which makes it hard to tell whether or not the model is actually dirty.

Comparison Operators

I was wondering is there was way to use the comparison operators that aren't mapped in this package.

For instance here is a list of the DynamoDb operators:

EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH | IN | BETWEEN

I'd like to say Message::where('key', 'BEGINS_WITH', 'val')

created_at/updated_at caveat

So yesterday, I ran into a fun issue, which resulted in a less than helpful error from Dynamo:

local.INFO: exception 'Aws\DynamoDb\Exception\DynamoDbException' with message 'Error executing "PutItem" on "http://localhost:8000"; AWS HTTP error: Client error: `POST http://localhost:8000` resulted in a `400 Bad Request` response:
{"__type":"com.amazon.coral.validate#ValidationException","message":"Type mismatch for attribute to update"}
 ValidationException (client): Type mismatch for attribute to update - {"__type":"com.amazon.coral.validate#ValidationException","message":"Type mismatch for attribute to update"}'

It took me a while to track down the issue, but eventually found it was due to Eloquent converting my Carbon timestamp into a DateTime. This caused the error, as I had set my created_at field to be a Number type, and obviously, strings aren't numbers.

So, after all of this, it might be worth adding a caveat into the readme, stating if you wish to use created_at/updated_at in your table, you should override the getDates() method on your model.

Mine looks like this:

/**
 * {@inheritdoc}
 */
public function getDates() {
    return [];
}

Collection Filters

When i try to run laravel collection functions on the collection it fails, it returns an empty array and/or items collection

Supported methods errors

I got error when I try to use
$model->find(<id>);

My code:
$u = new User();
echo $u->find('anyID');

Error:
ErrorException in Str.php line 424:
Illegal offset type in isset

As well as another function such as

$result = $u->where('key', 'key value')->get();
print_r($result);

Error:
ErrorException in DynamoDbQueryBuilder.php line 295:
Array to string conversion

My Laravel version is 5.3, The similar errors also occur in another method.

Installation Error

I followed the instructions and I got the following error

FatalErrorException in ProviderRepository.php line 146:
Class 'BaoPham\DynamoDb\DynamoDbServiceProvider' not found

I haven't done Laravel in a while, what am I doing wrong?

Set IndexName manually?

Hi, I have this:

protected $dynamoDbIndexKeys = [
    'user_id'   => 'user_index',
    'flg_state' => 'state_index',
];

It works as expected when there is one condition at once:

$this->where('user_id', 'abc-xyz')->get();
$this->where('flg_state', 0)->get();

But when there are multiple conditions

$this->where('user_id', 'abc-xyz')->where('flg_state', 0)->get();

I can not specify which index I want to use.

Is it OK to have a function to set IndexName manually like $this->indexName('index_name'); ?

Ordering

Hello.

How can I achieve ordering ? I'm getting confused trying to set it up.

how to use it

i have installed the package & updated the dynamo version to the newest (2016-05-17_1.0) and now am kinda lost

  • the dynamo config is added to services, which mean i have to use a db or else i would get
    SQLSTATE[HY000] [2002] No such file or directory

  • am using dynamo in local, and am not sure do i still need to add the key & secret or not

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.