baopham / laravel-dynamodb

Eloquent syntax for DynamoDB
https://packagist.org/packages/baopham/dynamodb
MIT License
484 stars 128 forks source link

Exception on Creating Duplicate results? #240

Closed d3vilsn0w closed 3 years ago

d3vilsn0w commented 3 years ago

I am already using PK tell Dynamo to not insert duplicate data, but it doesn't throw an exception when i do again, for example a multidimensional array with 4 data array. It still returns the count of 4 even when it already exists in database, Want it to return 0 as it does on Eloquent?

zoe-edwards commented 3 years ago

Dynamo doesn’t really work like this because of the way data is managed. If you show us your code we can make a suggestion on how to mange it.

d3vilsn0w commented 3 years ago

Dynamo doesn’t really work like this because of the way data is managed. If you show us your code we can make a suggestion on how to mange it.

Thanks for getting back to me Thomas. Sorry i been away for few days so i could not answer earlier.

Currently i am using model::upsert function to insert the data (including few duplicate array), which prevent the creation of duplicate rows, and return the count of rows, that were added successfully.

I am looking for something similar to scale my application on DynamoDB.

For example.

    $records = [
        [
            'id' => 1231, //PK, to avoid duplication
            'chainId' => '333'
        ],
        [
            'id' => 1231,
            'chainId' => '333'
        ],
        [
            'id' => 21434,
            'chainId' => '444'
        ],
        [
            'id' => 435453453,
            'chainId' => '555'
        ],
    ];

    foreach ($records as $record) {
        $result = AWS::create($record);
        $result->save();
    }

When pushing this records to dynamo, i want it to ignore the duplications and return the exact number of counts, in this case. it is 3 rows that were added. Instead Dynamo is updating the data if the row is already is in table. Is it possible to get this done? Very important for me.

zoe-edwards commented 3 years ago

Not possible I’m afraid. DynamoDB can’t detect that as when you push data to it, it is one-way. There’s no upsert feature for Dynamo in the same way you might imagine – a similar thing is possible but you’d have to make it yourself, but it isn’t possible with this package.

Dynamo does not work well with integer primary keys. It’s recommended to use UUIDs instead.

How I make UUIDs:

use Illuminate\Support\Str;

$lovelyUser = new LovelyUser();
$lovelyUser->id = (string) Str::uuid();
d3vilsn0w commented 3 years ago

Not possible I’m afraid. DynamoDB can’t detect that as when you push data to it, it is one-way. There’s no upsert feature for Dynamo in the same way you might imagine – a similar thing is possible but you’d have to make it yourself, but it isn’t possible with this package.

Dynamo does not work well with integer primary keys. It’s recommended to use UUIDs instead.

How I make UUIDs:

use Illuminate\Support\Str;

$lovelyUser = new LovelyUser();
$lovelyUser->id = (string) Str::uuid();

Thanks, Is there any way to achieve this with some modifications, It is very important for me and my servers goes almost down, or has a very high latency upto almost a minute due to overload. I thought Dynamo would be a best option to avoid such situation.

zoe-edwards commented 3 years ago

Yeah Dynamo can withstand a lot of pressure if you have auto scaling on – but your server will be the bottleneck, so it depends what you’re actually trying to do. If you need 99.99% uptime, then I would call on external help because that requires a lot of assistance to do. Good luck.

d3vilsn0w commented 3 years ago

May be something like that can help? https://www.dynamodbguide.com/expression-basics/#condition-expressions

zoe-edwards commented 3 years ago

In theory yes – but also no. What you have to remember is that the way that Dynamo works, writes are one-way. You can have two people both create the same item at the same time and it’ll work, because when they both created it there was none. Unlike things like MySQL, there is no locking. Conditional expressions are for managing the attributes within an item, not the item itself.

I think if you really need what you’re trying to do, DynamoDB is not for you. I would use MySQL instead.

d3vilsn0w commented 3 years ago

I ended up using Aurora instead with Lamdba, hope that would get the job done. Thanks Thomas for clarification.

zoe-edwards commented 3 years ago

Yeah I think that’ll work well for you!