# Differences from Dynamo

### Differences from Dynamo

Tynamo does not have to list every argument name used in an expression. This is because properties in Value Item (beginning with `:`) or entity properties (beginning with `#` ) are automatically written down. Consider the following expression.

```typescript
{
    conditionalExpressions : "attribute_not_exists(#id) and :a < :b"
}
```

The above expression requires one entity property and two value property. Thus, Tynamo infers the following objects:

```typescript
{
    ExpressionAttributeNames : {
        "#id" : "id"
    },
    ExpressionAttributeValues : {
        ":a" : { N|S|B : "?"},
        ":b" : { N|S|B : "?"}
    }
}
```

However, `ExpressionAttributeValues` ​​is an argument of `AttributeMap` type, which violates Tynamo  design principles. As an alternative, use the following value class:

```typescript
@DynamoEntity()
class MyExpressionValue {
    @DynamoProperty({ keyType: KeyType.hash })
    a!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    b!: number;
    
    constructor(a:number, b:number){
        this.a = a;
        this.b = b;
    }
}
```

{% hint style="info" %}
Currently, one `HASH` must be required in the ValueEntityClass also.
{% endhint %}

Attempting to use an argument that is not in the `EntityClass` or `ValueEntityClass` occurs error.

### Custom EntityPropertyName

It is also possible to set an alias for the EntityProperty. If you want to use the name `#identifier` instead of `id`, you can pass it explicitly in `ExpressionAttrubuteNames`.

```typescript
{
    conditionalExpressions : "attribute_not_exists(#identifier)",
    ExpressionAttributeNames : {
        "#identifier" : "id"
    }
}
```

Inferences made by Tynamo may conflict with what you explicitly conveyed. In this case, use the one passed explicitly.

```typescript
{
    conditionalExpressions : "attribute_not_exists(#name)",
    ExpressionAttributeNames : {
        "#name" : "id"
    }
}
```

Although a  `name` exists in the entity, it is used as aslias of `id`.

### Skip unnecessary elements

Dynamo raises an error if there is a declared but unused value name. Tynamo finds these elements and helps them to be omitted at the time of the actual call. For example,

```typescript
@DynamoEntity()
class ValueItem {
    @DynamoProperty({ keyType: KeyType.hash })
    a!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    b!: number;

    constructor(a: number, b: number) {
        this.a = a;
        this.b = b;
    }
}

{
    conditionalExpressions : "attribute_not_exists(#id)",
    ExpressionAttributeNames: {
        "#unused" : "name"
    },
    ExpressionAttributeValues : new ValueItem(0, 0)
}
```

In the expression above, `#unused`, `:a`, and `:b` are declared but not used. Dynamo raises an error if there is such an element, but Tynamo sends only the element that is actually used so no error occurs. It is good for `DynamicExpression`.

### Example

```typescript
@DynamoEntity()
class Cat {
    @DynamoProperty({ keyType: KeyType.hash })
    id!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    name!: string;

    constructor(id: number, name: string) {
        this.id = id;
        this.name = name;
    }
}

@DynamoEntity()
class ValueItem {
    @DynamoProperty({ keyType: KeyType.hash })
    a!: number;

    @DynamoProperty({ keyType: KeyType.attr })
    b!: number;

    constructor(a: number, b: number) {
        this.a = a;
        this.b = b;
    }
}

const tynamo: Tynamo = new Tynamo({
    region: "ap-northeast-2",
    endpoint: "http://localhost:8000"
});

await tynamo.putItem({
    Item: new Cat(666, "garfield"),
    ConditionExpression: "attribute_not_exists(#id) and :a < :b",
    ExpressionAttributeValues : new ValueItem(5, 0)
});
```

The above `putItem`  opreration is always fails because `:a < :b` is false.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aerocode.gitbook.io/tynamo/expression/differences-from-dynamo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
