{"id":13624984,"url":"https://github.com/awslabs/dynein","last_synced_at":"2025-10-21T03:58:42.470Z","repository":{"id":37010247,"uuid":"312885986","full_name":"awslabs/dynein","owner":"awslabs","description":"DynamoDB CLI written in Rust.","archived":false,"fork":false,"pushed_at":"2025-08-07T15:07:50.000Z","size":1241,"stargazers_count":391,"open_issues_count":25,"forks_count":39,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-09-09T06:31:12.830Z","etag":null,"topics":["aws","backup","cli","command-line","command-line-tool","database","ddb","dynamodb","dynamodb-admin","dynamodb-cli","dynamodb-client","dynamodb-local","export","import","nosql","rust"],"latest_commit_sha":null,"homepage":"https://github.com/awslabs/dynein","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awslabs.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":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-11-14T19:20:34.000Z","updated_at":"2025-08-08T16:02:43.000Z","dependencies_parsed_at":"2023-09-28T11:01:50.981Z","dependency_job_id":"f05e82bc-7e5a-4d3b-9ffe-9334b600ddc6","html_url":"https://github.com/awslabs/dynein","commit_stats":{"total_commits":121,"total_committers":14,"mean_commits":8.642857142857142,"dds":0.5950413223140496,"last_synced_commit":"1a9f173275639560646c4b73aca6377226fd8705"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/awslabs/dynein","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Fdynein","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Fdynein/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Fdynein/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Fdynein/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awslabs","download_url":"https://codeload.github.com/awslabs/dynein/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awslabs%2Fdynein/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280200870,"owners_count":26289477,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","backup","cli","command-line","command-line-tool","database","ddb","dynamodb","dynamodb-admin","dynamodb-cli","dynamodb-client","dynamodb-local","export","import","nosql","rust"],"created_at":"2024-08-01T21:01:49.172Z","updated_at":"2025-10-21T03:58:42.436Z","avatar_url":"https://github.com/awslabs.png","language":"Rust","funding_links":[],"categories":["Rust","cli"],"sub_categories":[],"readme":"dynein - DynamoDB CLI\n========================================\n\n**dynein** /daɪ.nɪn/ is a command line interface for [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) written in Rust. dynein is designed to make it simple to interact with DynamoDB tables/items from terminal.\n\n\u003c!-- TOC --\u003e\n\n- [Why use dynein?](#why-use-dynein)\n    - [Less Typing](#less-typing)\n    - [Quick Start](#quick-start)\n    - [For day-to-day tasks](#for-day-to-day-tasks)\n- [Installation](#installation)\n    - [Method 1. Download binaries](#method-1-download-binaries)\n    - [Method 2. Homebrew (MacOS)](#method-2-homebrew-macos)\n    - [Method 3. Building from source](#method-3-building-from-source)\n- [How to Use](#how-to-use)\n    - [Prerequisites - AWS Credentials](#prerequisites---aws-credentials)\n    - [Commands overview](#commands-overview)\n    - [Bootstrapping sample DynamoDB tables](#bootstrapping-sample-dynamodb-tables)\n    - [Working with DynamoDB tables](#working-with-dynamodb-tables)\n        - [Infrastracture as Code - enpowered by CloudFormation](#infrastracture-as-code---enpowered-by-cloudformation)\n        - [`dy use` and `dy config` to switch/manage context](#dy-use-and-dy-config-to-switchmanage-context)\n    - [Working with DynamoDB items](#working-with-dynamodb-items)\n        - [Read](#read)\n            - [`dy scan`](#dy-scan)\n            - [`dy get`](#dy-get)\n            - [`dy query`](#dy-query)\n        - [Write](#write)\n            - [`dy put`](#dy-put)\n            - [`dy upd`](#dy-upd)\n            - [`dy del`](#dy-del)\n    - [Working with Indexes](#working-with-indexes)\n    - [Import/Export for DynamoDB items](#importexport-for-dynamodb-items)\n        - [`dy export`](#dy-export)\n        - [`dy import`](#dy-import)\n    - [Using DynamoDB Local with `--region local` option](#using-dynamodb-local-with---region-local-option)\n- [Contribution](#contribution)\n- [Misc](#misc)\n    - [Asides](#asides)\n    - [Troubleshooting](#troubleshooting)\n    - [Ideas for future works](#ideas-for-future-works)\n\n\u003c!-- /TOC --\u003e\n\n\n# Why use dynein?\n\n## Less Typing\n\n- Auto completion for table/keyDefinitions enables using DynamoDB with minimum arguments. e.g. to get an item: `dy get abc`\n- Switching table context by RDBMS-ish \"use\".\n- Prefer standard JSON ( `{\"id\": 123}` ) over DynamoDB JSON ( `{\"id\": {\"N\": \"123\"}}` ).\n\n## Quick Start\n\n- [Bootstrap command](#bootstrapping-sample-dynamodb-tables) enables you to launch sample table with sample data sets.\n- Supports DynamoDB Local and you can test DyanmoDB at no charge.\n\n## For day-to-day tasks\n\n- Import/Export by single command: export DynamoDB items to CSV/JSON files and conversely, import them into tables.\n- Taking on-demand backup and restore data from them.\n\n\n# Installation\n\n## Method 1. Download binaries\n\nYou can download binaries of a specific version from [the releases page](https://github.com/awslabs/dynein/releases). For example, below instructions are example comamnds to download the latest version in each platform.\n\n### macOS\n\n```\n$ curl -O -L https://github.com/awslabs/dynein/releases/latest/download/dynein-macos.tar.gz\n$ tar xzvf dynein-macos.tar.gz\n$ mv dy /usr/local/bin/\n$ dy --help\n```\n\n### macOS (ARM 64)\n\n```\n$ curl -O -L https://github.com/awslabs/dynein/releases/latest/download/dynein-macos-arm.tar.gz\n$ tar xzvf dynein-macos-arm.tar.gz\n$ mv dy /usr/local/bin/\n$ dy --help\n```\n\n### Linux (x86-64)\n\n```\n$ curl -O -L https://github.com/awslabs/dynein/releases/latest/download/dynein-linux.tar.gz\n$ tar xzvf dynein-linux.tar.gz\n$ sudo mv dy /usr/local/bin/\n$ dy --help\n```\n\n\n## Method 2. Homebrew (macOS/Linux)\n\n```\n$ brew install dynein\n```\n\n## Method 3. Building from source\n\ndynein is written in Rust, so you can build and install dynein with Cargo. To build dynein from source code you need to [install Rust](https://www.rust-lang.org/tools/install) as a prerequisite.\n\n```\n$ git clone [[this_git_repository_url]]\n$ cd dynein\n$ cargo install --locked --path .\n$ ./target/release/dy --help\n```\n\nYou can move the binary file named \"dy\" to anywhere under your `$PATH`.\n\n\n# How to Use\n\n## Prerequisites - AWS Credentials\n\nFirst of all, please make sure you've already configured AWS Credentials in your environment. dynein depends on [aws-sdk-rust](https://github.com/awslabs/aws-sdk-rust) - for example `~/.aws/credentials` file, [IAM EC2 Instance Profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html), or environment variables such as `AWS_DEFAULT_REGION / AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_PROFILE`.\n\nOne convenient way to check if your AWS credential configuration is ok to use dynein is to install and try to execute [AWS CLI](https://aws.amazon.com/cli/) in your environment (e.g. `$ aws dynamodb list-tables`). Once you've [configured AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html), you should be ready to use dynein.\n\n\n## Commands overview\n\nAfter you installed dynein you should have a binary named `dy` in your `$PATH`. The first command you can try is `dy ls`, which lists tables you have:\n\n```\n$ dy ls --all-regions\nDynamoDB tables in region: us-west-2\n  EventData\n  EventUsers\n* Forum\n  Thread\nDynamoDB tables in region: us-west-1\n  No table in this region.\nDynamoDB tables in region: us-east-2\n  UserBooks\n  Users\n...\n```\n\nHere `--all-regions` option enables you to iterate over all AWS regions and list all tables for you.\n\nNext you can try `dy scan` with region and table options. `dy scan` command executes [Scan API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) internally to retrieve all items in the table.\n\n```\n$ dy scan --region us-west-2 --table Forum\nName             attributes\nAmazon S3        {\"Category\":\"Amazon Web Services\"}\nAmazon DynamoDB  {\"Views\":1000,\"Threads\":2,\"Messages\":4,\"Category\":...\n```\n\nHere `Name` is [a primary key](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey) of this `Forum` table and `attributes` column contains rest attributes of each item.\n\nYou don't want to pass `--region` and `--table` everytime? Let's mark the table as \"currently using\" with the command `dy use`.\n\n```\n$ dy use Forum --region us-west-2\n```\n\nNow you can interact with the table without specifying a target.\n\n```\n$ dy scan\nName             attributes\nAmazon S3        {\"Category\":\"Amazon Web Services\"}\nAmazon DynamoDB  {\"Threads\":2,\"Views\":1000,\"Messages\":4,\"Category\":...\n```\n\nTo find more features, `dy help` will show you complete list of available commands.\n\n```\n$ dy --help\ndynein x.x.x\ndynein is a command line tool to interact with DynamoDB tables/data using concise interface.\ndynein looks for config files under $HOME/.dynein/ directory.\n\nUSAGE:\n    dy [OPTIONS] \u003cSUBCOMMAND\u003e\n\nFLAGS:\n    -h, --help       Prints help information\n    -V, --version    Prints version information\n\nOPTIONS:\n    -r, --region \u003cregion\u003e    The region to use (e.g. --region us-east-1). When using DynamodB Local, use `--region\n                             local`. You can use --region option in both top-level and subcommand-level\n    -t, --table \u003ctable\u003e      Target table of the operation. You can use --table option in both top-level and subcommand-\n                             level. You can store table schema locally by executing `$ dy use`, after that\n                             you need not to specify --table on every command\n\nSUBCOMMANDS:\n    admin        \u003csub\u003e Admin operations such as creating/updating table or GSI\n    backup       Take backup of a DynamoDB table using on-demand backup\n    bootstrap    Create sample tables and load test data for bootstrapping\n    bwrite       Put or Delete multiple items at one time, up to 25 requests. [API: BatchWriteItem]\n    config       \u003csub\u003e Manage configuration files (config.yml and cache.yml) from command line\n    del          Delete an existing item. [API: DeleteItem]\n    desc         Show detailed information of a table. [API: DescribeTable]\n    export       Export items from a DynamoDB table and save them as CSV/JSON file\n    get          Retrieve an item by specifying primary key(s). [API: GetItem]\n    help         Prints this message or the help of the given subcommand(s)\n    import       Import items into a DynamoDB table from CSV/JSON file\n    list         List tables in the region. [API: ListTables]\n    put          Create a new item, or replace an existing item. [API: PutItem]\n    query        Retrieve items that match conditions. Partition key is required. [API: Query]\n    restore      Restore a DynamoDB table from backup data\n    scan         Retrieve items in a table without any condition. [API: Scan]\n    upd          Update an existing item. [API: UpdateItem]\n    use          Switch target table context. After you use the command you don't need to specify table every time,\n                 but you may overwrite the target table with --table (-t) option\n```\n\ndynein consists of multiple layers of subcommands. For example, `dy admin` and `dy config` require you to give additional action to run.\n\n```\n$ dy admin --help\ndy-admin x.x.x\n\u003csub\u003e Admin operations such as creating/updating table or GSI\n\nUSAGE:\n    dy admin [OPTIONS] \u003cSUBCOMMAND\u003e\n\nFLAGS: ...\n\nOPTIONS: ...\n\nSUBCOMMANDS:\n    create    Create new DynamoDB table or GSI. [API: CreateTable, UpdateTable]\n    delete    Delete a DynamoDB table or GSI. [API: DeleteTable]\n    desc      Show detailed information of a table. [API: DescribeTable]\n    help      Prints this message or the help of the given subcommand(s)\n    list      List tables in the region. [API: ListTables]\n    update    Update a DynamoDB table. [API: UpdateTable etc]\n```\n\nBy executing following command, you can create a DynamoDB table.\n\n```\n$ dy admin create table mytable --keys pk,S\n```\n\n\n## Bootstrapping sample DynamoDB tables\n\nThe easiest way to get familiar with dynein and DynamoDB would be executing `dy bootstrap`. The `bootstrap` subcommand creates sample tables and automatically load sample data defined [here](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AppendixSampleTables.html). After that, you'll see some sample commands to demonstrate basic usage of dynein.\n\n```\n$ dy bootstrap\n\nBootstrapping - dynein will creates 4 sample tables defined here:\nhttps://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AppendixSampleTables.html\n\n'ProductCatalog' - simple primary key table\n    Id (N)\n\n'Forum' - simple primary key table\n    Name (S)\n\n'Thread' - composite primary key table\n    ForumName (S)\n    Subject (S)\n\n'Reply' - composite primary key table, with GSI named 'PostedBy-Message-Index'\n    Id (S)\n    ReplyDateTime (S)\n\n...(snip logs)...\n\nNow all tables have sample data. Try following commands to play with dynein. Enjoy!\n  $ dy --region us-west-2 ls\n  $ dy --region us-west-2 desc --table Thread\n  $ dy --region us-west-2 scan --table Thread\n  $ dy --region us-west-2 use --table Thread\n  $ dy scan\n\nAfter you 'use' a table like above, dynein assume you're using the same region \u0026 table, which info is stored at ~/.dynein/config.yml and ~/.dynein/cache.yml\nLet's move on with the 'us-west-2' region you've just 'use'd...\n  $ dy scan --table Forum\n  $ dy scan -t ProductCatalog\n  $ dy get -t ProductCatalog 101\n  $ dy query -t Reply \"Amazon DynamoDB#DynamoDB Thread 2\"\n  $ dy query -t Reply \"Amazon DynamoDB#DynamoDB Thread 2\"  --sort-key \"begins_with 2015-10\"\n```\n\nIf you're interested in other available sample tables with data, check `dy bootstrap --list` and pass desired target to `--sample` option.\n\n\n## Working with DynamoDB tables\n\nUsing dynein, you can create a table:\n\n```\n$ dy admin create table app_users --keys app_id,S user_id,S\n---\nname: app_users\nregion: us-east-1\nstatus: CREATING\nschema:\n  pk: app_id (S)\n  sk: user_id (S)\nmode: OnDemand\ncapacity: ~\ngsi: ~\nlsi: ~\nstream: ~\ncount: 0\nsize_bytes: 0\ncreated_at: \"2020-03-03T13:34:43+00:00\"\n```\n\nAfter the table get ready (i.e. `status: CREATING` changed to `ACTIVE`), you can write-to and read-from the table.\n\n```\n$ dy use app_users\n$ dy desc\n---\nname: app_users\nregion: us-east-1\nstatus: ACTIVE\nschema:\n  pk: app_id (S)\n  sk: user_id (S)\nmode: OnDemand\ncapacity: ~\ngsi: ~\nlsi: ~\nstream: ~\ncount: 0\nsize_bytes: 0\ncreated_at: \"2020-03-03T13:34:43+00:00\"\n\n$ dy put myapp 1234 --item '{\"rank\": 99}'\nSuccessfully put an item to the table 'app_users'.\n\n$ dy scan\napp_id  user_id  attributes\nmyapp   1234     {\"rank\":99}\n```\n\nSimilarly you can update tables with dynein.\n\n```\n$ dy admin update table app_users --mode provisioned --wcu 10 --rcu 25\n```\n\n\n### Infrastracture as Code - enpowered by CloudFormation\n\nNOTE: currently this feature is under development\n\n[Infrastracture as Code](https://www.martinfowler.com/bliki/InfrastructureAsCode.html) is a concept that you define code to provision \"infrastructures\", such as DynamoDB tables, with \"declarative\" way (On the other hand you can say `dy admin create table` and `dy admin update table` commands are \"imperative\" way).\n\nTo manage DynamoDB tables with \"declarative\" way, dynein provides `dy admin plan` and `dy admin apply` commands. Internally dynein executes [AWS CloudFormation](https://aws.amazon.com/cloudformation/) APIs to provision DynamoDB resources for you.\n\n```\n$ ls\nmytable.cfn.yml\n\n$ cat mytable.cfn.yml\nResources:\n  MyDDB:\n    Type: AWS::DynamoDB::Table\n    Properties:\n      AttributeDefinitions:\n      - AttributeName: pk\n        AttributeType: S\n      KeySchema:\n      - AttributeName: pk\n        KeyType: HASH\n      BillingMode: PAY_PER_REQUEST\n\n(currently not available) $ dy admin plan\n(currently not available) $ dy admin apply\n```\n\nCloudFormation manages DynamoDB tables through the resource type named [AWS::DynamoDB::Table](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html) - visit the link for more information.\n\n\n### `dy use` and `dy config` to switch/manage context\n\nBasically it's pretty straight forward to specify table with which you want to interact with: `--table` or `-t` option. Let's say you want to scan data in the `customers` table.\n\n```\n$ dy scan --table customers\n... display items in the \"customers\" table ...\n```\n\nHowever, dynein assume that tipically you're interested in only one table at some point. It means that passing table name for every single command execution is a kinf of waste of your time.\n\nBy using `dy use` for a table, you can call commands such as `scan`, `get`, `query`, and `put` without specifying table name.\n\n```\n$ dy use customers\n$ dy scan\n... display items in the \"customers\" table ...\n```\n\nIn detail, when you execute `dy use` command, dynein saves your table usage information in `~/.dynein/config.yml` and caches table schema in `~/.dynein/cache.yml`. You can dump them with `dy config dump` command.\n\n```\n$ ls ~/.dynein/\ncache.yml   config.yml\n\n$ dy config dump\n---\ntables:\n  ap-northeast-1/customers:\n    region: ap-northeast-1\n    name: customers\n    pk:\n      name: user_id\n      kind: S\n    sk: ~\n    indexes: ~\n---\nusing_region: ap-northeast-1\nusing_table: customers\n```\n\nTo clear current table configuration, simply execute `dy config clear`.\n\n```\n$ dy config clear\n$ dy config dump\n---\ntables: ~\n---\nusing_region: ~\nusing_table: ~\n```\n\n\n## Working with DynamoDB items\n\nAs an example let's assume you have [official \"Movie\" sample data](https://raw.githubusercontent.com/awsdocs/aws-doc-sdk-examples/c2edcff1365d4b454b51075d632a1be844dd3e47/resources/sample_files/movies.json). To prepare the table with data loaded, simply you can execute `dy bootstrap --sample movie`.\n\n```\n$ dy bootstrap --sample movie\n... wait some time while dynein loading data ...\n$ dy use Movie\n```\n\nAfter executing `dy use \u003cyour_table\u003e` command, dynein recognize keyscheme and data type of the table. It means that some of the arguments you need to pass to access data (items) is automatically inferred when possible.\n\n\nBefore diving deep into each command, let me describe DynamoDB's \"reserved words\". One of the traps that beginners can easily fall into is that you cannot use [certain reserved words](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) in DynamoDB APIs. DynamoDB reserved words contains common words that you may want to use in your application. For example \"name\", \"year\", \"url\", \"token\", \"error\", \"date\", \"group\" -- all of them are reserved so you cannot use them in expressions directly.\n\nNormally, to use reserved words in expressions, you need to use placeholders instead of actual values. For more information, see [Expression Attribute Names](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html) and [Expression Attribute Values](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeValues.html).\n\nTo make it easy to interact with DynamoDB items, dynein automatically replace reserved words to placeholders internally - thus you don't need to care about it.\n\n### Read\n\n#### `dy scan`\n\nThe simplest command would be `dy scan`, which list items in a table.\n\n```\n$ dy scan --limit 10\nyear  title                  attributes\n1933  King Kong              {\"info\":{\"actors\":[\"Bruce Cabot\",\"Fay Wray\",\"Rober...\n1944  Arsenic and Old Lace   {\"info\":{\"actors\":[\"Cary Grant\",\"Priscilla Lane\",\"...\n1944  Double Indemnity       {\"info\":{\"actors\":[\"Barbara Stanwyck\",\"Edward G. R...\n1944  I'll Be Seeing You     {\"info\":{\"actors\":[\"Ginger Rogers\",\"Joseph Cotten\"...\n1944  Lifeboat               {\"info\":{\"actors\":[\"John Hodiak\",\"Tallulah Bankhea...\n1958  Cat on a Hot Tin Roof  {\"info\":{\"actors\":[\"Burl Ives\",\"Elizabeth Taylor\",...\n1958  Monster on the Campus  {\"info\":{\"actors\":[\"Arthur Franz\",\"Joanna Moore\",\"...\n1958  No Time for Sergeants  {\"info\":{\"actors\":[\"Andy Griffith\",\"Myron McCormic...\n1958  Teacher's Pet          {\"info\":{\"actors\":[\"Clark Gable\",\"Doris Day\",\"Gig ...\n1958  Touch of Evil          {\"info\":{\"actors\":[\"Charlton Heston\",\"Janet Leigh\"...\n```\n\n\n#### `dy get`\n\nYou may notice that non-key attributes are trimmed in above `dy scan` results. To get full details of a single item, you use `dy get` command with primary key. As the \"Movie\" table is defined with [composite primary key](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey), you have to pass \"partition key (= year) and \"sort key (= title)\" to identify an item.\n\n```\n$ dy desc\n---\nname: Movie\nregion: us-west-2\nstatus: ACTIVE\nschema:\n  pk: year (N)     \u003c\u003c\u003c\u003c=== \"year\" and\n  sk: title (S)    \u003c\u003c\u003c\u003c=== \"title\" are the information to identify an item.\n...\n\n$ dy get 1958 \"Touch of Evil\"\n{\n  \"info\": {\n    \"actors\": [\n      \"Charlton Heston\",\n      \"Janet Leigh\",\n      \"Orson Welles\"\n    ],\n    \"directors\": [\n      \"Orson Welles\"\n    ],\n    \"genres\": [\n      \"Crime\",\n      \"Film-Noir\",\n      \"Thriller\"\n    ],\n    \"image_url\": \"http://ia.media-imdb.com/images/M/MV5BNjMwODI0ODg1Nl5BMl5BanBnXkFtZTcwMzgzNjk3OA@@._V1_SX400_.jpg\",\n    \"plot\": \"A stark, perverse story of murder, kidnapping, and police corruption in a Mexican border town.\",\n    \"rank\": 3843,\n    \"rating\": 8.2,\n    \"release_date\": \"1958-04-23T00:00:00Z\",\n    \"running_time_secs\": 5700\n  },\n  \"title\": \"Touch of Evil\",\n  \"year\": 1958\n}\n```\n\nNote that if your table has a simple primary key, the only argument you need to pass is a partition key (e.g. `dy get yourpk`), as the only information DynamoDB requires to identify an item is only a partition key.\n\n\n#### `dy query`\n\nNext command you can try to retrieve items would be: `dy query`. By passing a partition key, `dy query` returns items that have the specified partition key.\n\n```\n$ dy query 1960\nyear  title                  attributes\n1960  A bout de souffle      {\"info\":{\"actors\":[\"Daniel Boulanger\",\"Jean Seberg...\n1960  La dolce vita          {\"info\":{\"actors\":[\"Anita Ekberg\",\"Anouk Aimee\",\"M...\n1960  Ocean's Eleven         {\"info\":{\"actors\":[\"Dean Martin\",\"Frank Sinatra\",\"...\n1960  Plein soleil           {\"info\":{\"actors\":[\"Alain Delon\",\"Marie Laforet\",\"...\n1960  Spartacus              {\"info\":{\"actors\":[\"Jean Simmons\",\"Kirk Douglas\",\"...\n1960  The Apartment          {\"info\":{\"actors\":[\"Fred MacMurray\",\"Jack Lemmon\",...\n1960  The Magnificent Seven  {\"info\":{\"actors\":[\"Charles Bronson\",\"Steve McQuee...\n1960  The Time Machine       {\"info\":{\"actors\":[\"Alan Young\",\"Rod Taylor\",\"Yvet...\n```\n\nAlso you can add more conditions on sort key. For example, following command would return items that has sort keys begins with \"The\".\n\n```\n$ dy query 1960 --sort-key \"begins_with The\"\nyear  title                  attributes\n1960  The Apartment          {\"info\":{\"actors\":[\"Fred MacMurray\",\"Jack Lemmon\",...\n1960  The Magnificent Seven  {\"info\":{\"actors\":[\"Charles Bronson\",\"Steve McQuee...\n1960  The Time Machine       {\"info\":{\"actors\":[\"Alan Young\",\"Rod Taylor\",\"Yvet...\n```\n\nOther examples for the `--sort-key` option of `dy query` are: `--sort-key \"= 42\"`, `--sort-key \"\u003e 42\"`, or `--sort-key \"between 10 and 42\"`.\nYou can find a more detailed explanation in the dedicated [`dy query` command document](./docs/query.md).\n\n### Write\n\ndynein provides subcommands to write to DynamoDB tables as well.\n\n\n#### `dy put`\n\n`dy put` internally calls [PutItem API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) and save an item to a target table.\nTo save an item, you need to pass at least primary key that identifies an item among the table.\n\n```\n$ dy admin create table write_test --keys id,N\n$ dy use write_test\n\n$ dy put 123\nSuccessfully put an item to the table 'write_test'.\n$ dy scan\nid  attributes\n123\n```\n\nAdditionally, you can include an item body (non-key attributes) by passing `--item` or `-i` option.\nThe `--item` option takes a JSON-style expression with extended syntax.\n\n```\n$ dy put 456 --item '{\"a\": 9, \"b\": \"str\"}'\nSuccessfully put an item to the table 'write_test'.\n\n$ dy scan\nid  attributes\n123\n456  {\"a\":9,\"b\":\"str\"}\n```\n\nAs the parameter of the `--item` option automatically transforms into DynamoDB-style JSON syntax,\nwriting items into a table would be more straightforward than AWS CLI.\nSee the following comparison:\n\n```\n$ dy put 789 --item '{\"a\": 9, \"b\": \"str\"}'\n\n// The above dynein command is equivalent to AWS CLI's following command:\n$ aws dynamodb put-item --table-name write_test --item '{\"id\": {\"N\": \"456\"}, \"a\": {\"N\": \"9\"}, \"b\": {\"S\": \"str\"}}'\n```\n\nPlease see the [dynein format](./docs/format.md) for details of JSON-style data.\nTo summarize, in addition to the string (\"S\") and number (\"N\"), dynein also supports other data types such as boolean (\"BOOL\"),\nnull (\"NULL\"), binary (\"B\"), string set (\"SS\"), number set (\"NS\"), binary set(\"BS\"),\nlist (\"L\"), and nested object (\"M\").\n\n```\n$ dy put 999 --item '{\"myfield\": \"is\", \"nested\": {\"can\": true, \"go\": false, \"deep\": [1,2,{\"this_is_set\": \u003c\u003c\"x\",\"y\",\"z\"\u003e\u003e}]}}'\nSuccessfully put an item to the table 'write_test'.\n$ dy get 999\n{\n  \"nested\": {\n    \"can\": true,\n    \"deep\": [\n      1,\n      2,\n      {\n        \"this_is_set\": [\n          \"x\",\n          \"y\",\n          \"z\"\n        ]\n      }\n    ],\n    \"go\": false\n  },\n  \"myfield\": \"is\",\n  \"id\": 999\n}\n```\n\n\n#### `dy upd`\n\n`dy upd` command internally executes [UpdateItem API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) and you use \"[update expression](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html)\" to update an item. Recommended way to update items is use `SET` and `REMOVE` in update expression.\n\nwith dynein, you can use `--set` or `--remove` option. Here's an exmaple:\n\n```bash\n$ dy put 42 -i '{\"flag\": true}'\nSuccessfully put an item to the table 'test'.\n\n$ dy get 42\n{\n  \"flag\": true,\n  \"id\": 42\n}\n\n# Set a boolean\n$ dy upd 42 --set \"flag = false\"\nSuccessfully updated an item in the table 'write_test'.\n\n$ dy get 42\n{\n  \"flag\": false,\n  \"id\": 42\n}\n\n# Set a string value\n$ dy upd 42 --set \"date = '2022-02-22T22:22:22Z'\"\n$ dy get 42\n{\n  \"date\": \"2022-02-22T22:22:22Z\",\n  \"id\": \"42\",\n  \"flag\": false\n}\n\n# Set a number\n$ dy upd 42 --set 'pi = +3.14159265358979323846'\n$ dy get 42\n{\n  \"date\": \"2022-02-22T22:22:22Z\",\n  \"pi\": 3.141592653589793,\n  \"id\": \"42\",\n  \"flag\": false\n}\n\n# You can apply an addition (+) and a subtraction (-) to the numbers. Please note that DynamoDB does not support unary operator (+, -), multiplication and division.\n$ dy upd 42 --set 'pi = pi + 10'\n$ dy get 42 | jq .pi\n13.141592653589793\n\n$ dy upd 42 --set 'pi = 1 - pi'\n$ dy get 42 | jq .pi\n-12.141592653589793\n```\n\nNext let me show an example to use `--remove`. Note that `--remove` in `dy upd` command never remove \"item\" itself, instead `--remove` just removes an \"attribute\".\n\n```bash\n$ dy upd 42 --remove flag\nSuccessfully updated an item in the table 'write_test'.\n\n$ dy get 42\n{\n  \"id\": \"42\",\n  \"date\": \"2022-02-22T22:22:22Z\",\n  \"pi\": 3.141592653589793\n}\n\n# You can remove multiple attributes\n$ dy upd 42 --remove \"date, pi\"\n$ dy get 42\n{\n  \"id\": \"42\"\n}\n```\n\nDynamoDB supports a list type which has order. Let's try it with dynein.\n\n```bash\n# Create an empty list\n$ dy upd 42 --set \"list = []\"\n$ dy get 42\n{\n  \"id\": \"42\",\n  \"list\": []\n}\n\n# Add an elements into the list\n$ dy upd 42 --set \"list = list_append(list, ['item1'])\"\n$ dy get 42\n{\n  \"id\": \"42\",\n  \"list\": [\n    \"item1\"\n  ]\n}\n\n# Prepend an element to the list\n$ dy upd 42 --set \"list = list_append(['item0'], list)\"\n$ dy get 42 | jq .list\n[\n  \"item0\",\n  \"item1\"\n]\n\n# Add more elements\n$ dy upd 42 --set \"list = list_append(list, ['item2', 'item3'])\"\n$ dy get 42 | jq .list\n[\n  \"item0\",\n  \"item1\",\n  \"item2\",\n  \"item3\"\n]\n\n# You can directly modify the list element\n$ dy upd 42 --set \"list[0] = 'item0 modified'\"\n$ dy get 42 | jq .list\n[\n  \"item0 modified\",\n  \"item1\",\n  \"item2\",\n  \"item3\"\n]\n\n# Delete the element from the list\n$ dy upd 42 --remove 'list[0]'\n$ dy get 42 | jq .list\n[\n  \"item1\",\n  \"item2\",\n  \"item3\"\n]\n\n# Remove the list attribute\n$ dy upd 42 --remove list\n$ dy get 42\n{\n  \"id\": \"42\"\n}\n```\n\nFurthermore, it's possible to update multiple attributes simultaneously.\n\n```bash\n# Set numbers\n$ dy upd 42 --set \"n1 = 0, n2 = 1\"\n$ dy get 42\n{\n  \"n2\": 1,\n  \"id\": \"42\",\n  \"n1\": 0\n}\n\n# Calculate Fibonacci numbers\n$ dy upd 42 --set \"n1 = n2, n2 = n1 + n2\"\n$ dy get 42 | jq -c '[.n1,.n2]'\n[1,1]\n\n# Calculate the next value\n$ dy upd 42 --set \"n1 = n2, n2 = n1 + n2\"\n$ dy get 42 | jq -c '[.n1,.n2]'\n[1,2]\n\n# You can get more sequence\n$ dy upd 42 --set \"n1 = n2, n2 = n1 + n2\"\n$ dy get 42 | jq -c '[.n1,.n2]'\n[2,3]\n\n$ dy upd 42 --set \"n1 = n2, n2 = n1 + n2\"\n$ dy get 42 | jq -c '[.n1,.n2]'\n[3,5]\n\n# Clean up the attributes\n$ dy upd 42 --remove \"n1,n2\"\n$ dy get 42\n{\n  \"id\": \"42\"\n}\n```\n\nAs demonstrated in `dy put`, map type expresses nested values. Let's manipulate it with dynein.\n\n```bash\n$ dy upd 42 --set 'ProductReviews = {\"metadata\": {\"counts\": 0, \"average\": null}}'\n$ dy get 42\n{\n  \"id\": \"42\",\n  \"ProductReviews\": {\n    \"metadata\": {\n      \"average\": null,\n      \"counts\": 0\n    }\n  }\n}\n\n$ dy upd 42 --set 'ProductReviews.FiveStar = [\"Excellent product\"], ProductReviews.metadata = {\"average\": 5, \"sum\": 5, \"counts\": 1}'\n$ dy get 42\n{\n  \"id\": \"42\",\n  \"ProductReviews\": {\n    \"FiveStar\": [\n      \"Excellent product\"\n    ],\n    \"metadata\": {\n      \"average\": 5,\n      \"counts\": 1,\n      \"sum\": 5\n    }\n  }\n}\n\n$ dy upd 42 --set 'ProductReviews.FiveStar[1] = \"Very happy with my purchase\", ProductReviews.ThreeStar = [\"Just OK - not that great\"], ProductReviews.metadata = {\"average\": 4.3, \"sum\": 13, \"counts\": 3}'\n$ dy get 42\n{\n  \"id\": \"42\",\n  \"ProductReviews\": {\n    \"FiveStar\": [\n      \"Excellent product\",\n      \"Very happy with my purchase\"\n    ],\n    \"ThreeStar\": [\n      \"Just OK - not that great\"\n    ],\n    \"metadata\": {\n      \"average\": 4.3,\n      \"counts\": 3,\n      \"sum\": 13\n    }\n  }\n}\n\n$ dy upd 42 --set 'ProductReviews.OneStar = if_not_exists(ProductReviews.OneStar, [])'\n$ dy get 42\n{\n  \"id\": \"42\",\n  \"ProductReviews\": {\n    \"FiveStar\": [\n      \"Excellent product\",\n      \"Very happy with my purchase\"\n    ],\n    \"OneStar\": [],\n    \"ThreeStar\": [\n      \"Just OK - not that great\"\n    ],\n    \"metadata\": {\n      \"average\": 4.3,\n      \"counts\": 3,\n      \"sum\": 13\n    }\n  }\n}\n\n$ dy upd 42 --set 'ProductReviews.OneStar = list_append(ProductReviews.OneStar, [\"Broken\"]), ProductReviews.metadata = {\"average\": 3.5, \"sum\": 14, \"counts\": 4}'\n$ dy get 42\n{\n  \"ProductReviews\": {\n    \"FiveStar\": [\n      \"Excellent product\",\n      \"Very happy with my purchase\"\n    ],\n    \"OneStar\": [\n      \"Broken\"\n    ],\n    \"ThreeStar\": [\n      \"Just OK - not that great\"\n    ],\n    \"metadata\": {\n      \"average\": 3.5,\n      \"counts\": 4,\n      \"sum\": 14\n    }\n  },\n  \"id\": \"42\"\n}\n\n$ dy upd 42 --remove ProductReviews\n$ dy get 42\n{\n  \"id\": \"42\"\n}\n```\n\ndynein has a special command named `--atomic-counter`. It increases specified number attribute by `1`.\n\n```bash\n$ dy get 52\n{\n  \"age\": 28,\n  \"name\": \"John\",\n  \"id\": 52\n}\n\n$ dy upd 52 --atomic-counter age\nSuccessfully updated an item in the table 'write_test'.\n\n$ dy get 52\n{\n  \"age\": 29,\n  \"id\": 52,\n  \"name\": \"John\"\n}\n```\n\n##### Supported String Literals\n\nThere are two types of string literals that you can use:\n\n- Double quote (`\"`): Double quoted string literals support escape sequences such as `\\0`, `\\r`, `\\n`, `\\t`, `\\\\`, `\\\"`, and `\\'`. Each of them represents a null character, carriage return, new line, horizontal tab, backslash, double quote, and single quote, respectively. If you need to include a double quote inside the literal, you must escape it.\n- Single quote (`'`): Single-quoted string literals are interpreted as you input them. However, you cannot specify a string that includes a single quote. In such cases, you can use a double-quoted string literal.\n\n##### Supported Functions\n\nThe `upd` command supports the following functions:\n\n- `list_append`: This function is used to concatenate two lists, where each list can be a literal or a path to an attribute. When you call `list_append([l1,l2], [l3,l4,l5])`, it will return `[l1,l2,l3,l4,l5]`.\n- `if_not_exists`: This fungiction allows you to set a default value for the `null` case. The left-hand argument represents the path to an attribute, while the right-hand argument specifies the default value for the `null`.\n\nFor more details, please refer to the [official documentation](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.SET.UpdatingListElements).\n\n#### Quoting a Path of an Attribute\n\nSometimes, you may need to specify a path that includes a space or special characters that are not allowed by dynein. In such cases, you can use backticks to quote the path. For example, consider the following item:\n\n```json\n{\n  \"id\": {\"S\":  \"55\"},\n  \"map\": {\n    \"M\": {\n      \"Do you have spaces?\": {\n        \"S\": \"Yes\"\n      },\n      \"Dou you `?\": {\n        \"S\": \"Yes\"\n      },\n      \"路径\": {\"S\": \"Chinese\"},\n      \"パス\": {\"S\": \"Japanese\"},\n      \"경로\": {\"S\": \"Korean\"}\n    }\n  }\n}\n```\n\nYou can specify a path using the following syntax:\n\n* ```dy upd 55 --set 'map.`Do you have spaces?` = \"Allowed\"'```\n* ```dy upd 55 --set 'map.`Dou you ``?` = \"Maybe\"'```\n\nAs demonstrated above, you can use double backticks (``) to represent a backtick (`) within the path.\n\nPlease note that you may not need to escape non-ASCII paths like CJK characters. For example, you can specify `路径`, `パス`, and `경로` without quotes. Dynein allows you to specify a path where the first character belongs to the `ID_Start` class and the subsequent characters belong to the `ID_Continue` class without requiring escape sequences. These classes are defined by the [Unicode standard](https://www.unicode.org/reports/tr31/tr31-37.html). The following examples illustrate this:\n\n* ```dy upd 55 --set 'map.路径 = \"A word of Chinese\"'```\n* ```dy upd 55 --set 'map.パス = \"A word of Japanese\"'```\n* ```dy upd 55 --set 'map.경로 = \"A word of Korean\"'```\n\n#### `dy del`\n\nTo delete an item, you use `dy del` command with primary key to identify an item.\n\n```bash\n$ dy get 42\n{ \"id\": 42 }\n$ dy del 42\nSuccessfully deleted an item from the table 'write_test'.\n$ dy get 42\nNo item found.\n```\n\n#### `dy bwrite`\n`dy bwrite` internally calls [BatchWriteItem API](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html) and is used for putting and deleting multiple items.\n\nYou can specify the `--input` option when providing operations from a JSON file that follows the Request Syntax of BatchWriteItem API.\n\n```bash\n$ dy bwrite --input request.json\n$ cat request.json\n{\n    \"__TABLE_NAME__\": [\n        {\n            \"PutRequest\": {\n                \"Item\": {\n                    \"pk\": { \"S\": \"ichi\" },\n                    \"ISBN\": { \"S\": \"111-1111111111\" },\n                    \"Price\": { \"N\": \"2\" },\n                    \"Dimensions\": { \"SS\": [\"Giraffe\", \"Hippo\" ,\"Zebra\"] },\n                    \"PageCount\": { \"NS\": [\"42.2\", \"-19\", \"7.5\", \"3.14\"] },\n                    \"InPublication\": { \"BOOL\": false },\n                    \"Binary\": {\"B\": \"dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk\"},\n                    \"BinarySet\": {\"BS\": [\"U3Vubnk=\", \"UmFpbnk=\", \"U25vd3k=\"]},\n                    \"Nothing\": { \"NULL\": true },\n                    \"Authors\": {\n                        \"L\": [\n                            { \"S\": \"Author1\" },\n                            { \"S\": \"Author2\" },\n                            { \"N\": \"42\" }\n                        ]\n                    },\n                    \"Details\": {\n                        \"M\": {\n                            \"Name\": { \"S\": \"Joe\" },\n                            \"Age\":  { \"N\": \"35\" },\n                            \"Misc\": {\n                                \"M\": {\n                                    \"hope\": { \"BOOL\": true },\n                                    \"dream\": { \"L\": [ { \"N\": \"35\" }, { \"NULL\": true } ] }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    ]\n}\n```\n\nYou can also use `--put` or `--del` options to achieve corresponding operations.\nThese options take the [dynein format](./docs/format.md), a JSON-style expression.\nTo put or delete items, you must provide at least a primary key to identify each item uniquely.\n\n```bash\n$ dy bwrite --put '{\"pk\": \"1\", \"this_is_set\": \u003c\u003c\"i\",\"j\",\"k\"\u003e\u003e}' --put '{\"pk\": \"2\", \"this_is_set\": \u003c\u003c\"x\",\"y\",\"z\"\u003e\u003e}'\n$ dy scan\npk  attributes\n1   {\"this_is_set\":[\"i\",\"j\",\"k\"]}\n2   {\"this_is_set\":[\"x\",\"y\",\"z\"]}\n```\n\nThe `--put`, `--del`, and `--input` options can be used simultaneously.\n\n```bash\n$ dy bwrite --del '{\"pk\": \"1\"}' --del '{\"pk\": \"2\"}' --put '{\"pk\": \"3\", \"this_is_set\": \u003c\u003c\"a\",\"b\",\"c\"\u003e\u003e}'\n$ dy scan\npk  attributes\n3   {\"this_is_set\":[\"a\",\"b\",\"c\"]}\n```\n\n```bash\n$ dy bwrite --del '{\"pk\": \"1\"}' --del '{\"pk\": \"2\"}' --put '{\"pk\": \"3\", \"this_is_set\": \u003c\u003c\"a\",\"b\",\"c\"\u003e\u003e}' --input request.json\n```\n\n## Working with Indexes\n\nDynamoDB provides flexible way to query data efficiently by utilizing [Secondary Index features](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html). There're two types of secondary indexes: GSI (Global Secondary Index) and LSI (Local Secondary Index), but you can create LSI only when creating a table.\n\nWith dynein, you can add GSI to existing table.\n\n```\n$ dy admin create index top_rank_users_index --keys rank,N --table app_users\n---\nname: app_users\nregion: us-west-2\nstatus: UPDATING\nschema:\n  pk: app_id (S)\n  sk: user_id (S)\nmode: OnDemand\ncapacity: ~\ngsi:\n  - name: top_rank_users_index\n    schema:\n      pk: rank (N)\n      sk: ~\n    capacity: ~\nlsi: ~\nstream: ~\ncount: 0\nsize_bytes: 0\ncreated_at: \"2020-06-02T14:22:56+00:00\"\n\n$ dy use app_users\n$ dy scan --index top_rank_users_index\n```\n\n## Import/Export for DynamoDB items\n\n### `dy export`\n\nYou can export DynamoDB items into JSON or CSV file. As the default format is json, you can simply call following command to export:\n\n```\n$ dy export --table Reply --format json --output-file out.json\n$ cat out.json\n[\n  {\n    \"PostedBy\": \"User A\",\n    \"ReplyDateTime\": \"2015-09-15T19:58:22.947Z\",\n    \"Id\": \"Amazon DynamoDB#DynamoDB Thread 1\",\n    \"Message\": \"DynamoDB Thread 1 Reply 1 text\"\n  },\n  {\n    \"Id\": \"Amazon DynamoDB#DynamoDB Thread 1\",\n...\n```\n\nNo `--format` option means `--format json`. If you want to dump data in oneline, try `--format json-compact`. Or, if you want to export in [JSONL (JSON Lines)](http://jsonlines.org/), i.e. \"one JSON item per one line\" style, `--format jsonl` is also available.\n\n```\n$ dy export --table Reply --format jsonl --output-file out.jsonl\n$ cat out.jsonl\n{\"PostedBy\":\"User A\",\"ReplyDateTime\":\"2015-09-15T19:58:22.947Z\",\"Message\":\"DynamoDB Thread 1 Reply 1 text\",\"Id\":\"Amazon DynamoDB#DynamoDB Thread 1\"}\n{\"PostedBy\":\"User B\",\"Message\":\"DynamoDB Thread 1 Reply 2 text\",\"ReplyDateTime\":\"2015-09-22T19:58:22.947Z\",\"Id\":\"Amazon DynamoDB#DynamoDB Thread 1\"}\n...\n```\n\nWhen export data to CSV, primary key(s) are exported by default. You can explicitly pass additional attributes to export.\n\n```\n$ dy export --table Reply --output-file out.csv --format csv --attributes PostedBy,Message\n$ cat out.csv\nId,ReplyDateTime,PostedBy,Message\n\"Amazon DynamoDB#DynamoDB Thread 1\",\"2015-09-15T19:58:22.947Z\",\"User A\",\"DynamoDB Thread 1 Reply 1 text\"\n...\n```\n\n### `dy import`\n\nTo import data into a table, you use with specified `--format` option. Here default format is JSON like `dy export`.\n\n```\n$ dy import --table target_movie --format json --input-file movie.json\n```\n\n#### Enable set type inference\n\nDynein provides the type inference for set types (number set, string set) for backward compatibility.\nIf you want to retain the inference behavior before 0.3.0, you can use `--enable-set-inference` option.\n\nWithout option, all JSON lists are inferred as list type.\n\n```bash\n$ cat load.json\n{\"pk\":1,\"string-set\":[\"1\",\"2\",\"3\"]}\n{\"pk\":2,\"number-set\":[1,2,3]}\n{\"pk\":3,\"list\":[\"1\",2,\"3\"]}\n\n$ dy admin create table target_movie -k pk,N\n$ dy import --table target_movie --format jsonl --input-file load.json\n$ aws dynamodb get-item --table-name target_movie --key '{\"pk\":{\"N\":\"1\"}}'\n{\n    \"Item\": {\n        \"string-set\": {\n            \"L\": [\n                {\n                    \"S\": \"1\"\n                },\n                {\n                    \"S\": \"2\"\n                },\n                {\n                    \"S\": \"3\"\n                }\n            ]\n        },\n        \"pk\": {\n            \"N\": \"1\"\n        }\n    }\n}\n```\n\nWith `--enable-set-inference` option, JSON lists are inferred based on their content.\n\n```bash\n$ dy admin create table target_movie2 -k pk,N\n$ dy import --table target_movie --format jsonl --enable-set-inference --input-file load.json\n$ aws dynamodb get-item eu-north-1 --table-name target_movie --key '{\"pk\":{\"N\":\"1\"}}'\n{\n    \"Item\": {\n        \"string-set\": {\n            \"SS\": [\n                \"1\",\n                \"2\",\n                \"3\"\n            ]\n        },\n        \"pk\": {\n            \"N\": \"1\"\n        }\n    }\n}\n\n$ aws dynamodb get-item --table-name target_movie --key '{\"pk\":{\"N\":\"2\"}}'\n{\n    \"Item\": {\n        \"pk\": {\n            \"N\": \"2\"\n        },\n        \"number-set\": {\n            \"NS\": [\n                \"3\",\n                \"2\",\n                \"1\"\n            ]\n        }\n    }\n}\n\n$ aws dynamodb get-item --table-name target_movie --key '{\"pk\":{\"N\":\"3\"}}'\n{\n    \"Item\": {\n        \"pk\": {\n            \"N\": \"3\"\n        },\n        \"list\": {\n            \"L\": [\n                {\n                    \"S\": \"1\"\n                },\n                {\n                    \"N\": \"2\"\n                },\n                {\n                    \"S\": \"3\"\n                }\n            ]\n        }\n    }\n}\n```\n\n## Using DynamoDB Local with `--region local` option\n\nDynamoDB provides [free tier](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank\u0026all-free-tier.sort-order=asc\u0026awsf.Free%20Tier%20Categories=*all\u0026all-free-tier.q=dynamodb\u0026all-free-tier.q_operator=AND) that consists of [25 GB of storage and 25 WCU/RCU](https://aws.amazon.com/dynamodb/pricing/provisioned/) which is enough to handle up to 200M requests per month. However, if you're already using DynamoDB in your account and worrying about additional costs by getting started with dynein, you can use [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html).\n\nYes, dynein supports DynamoDB Local. The only difference you need to add would be `--region local` option for every command. To get start with DynamoDB Local [Docker version](https://hub.docker.com/r/amazon/dynamodb-local) with dynein is quite simple as follows.\n\nSimply you can run docker container and expose 8000 port by following command.\n\n```\n$ docker run -p 8000:8000 -d amazon/dynamodb-local\n```\n\nOptionally, if you prefer Kubernetes, you can use manifest file in this repository.\n\n```\n$ kubectl apply -f k8s-deploy-dynamodb-local.yml\n$ kubectl port-forward deployment/dynamodb 8000:8000\n```\n\nNow you can interact with DynamoDB Local with `--region local` option.\n\n```\n$ dy --region local admin create table localdb --keys pk\n$ dy --region local use -t localdb\n$ dy put firstItem\n$ dy put secondItem\n$ dy scan\n```\n\n\n# Contribution\nWe welcome community contributions and pull requests. See [CONTRIBUTING.md](CONTRIBUTING.md) for our guidelines\non how to submit your code.\n\n\n# Misc\n## Asides\n\ndynein is named after [a motor protein](https://en.wikipedia.org/wiki/Dynein).\n\n## Troubleshooting\n\nIf you encounter troubles, the first option worth trying is removing files in `~/.dynein/` or the directory itself. Doing this just clears \"cached\" info stored locally for dynein and won't affect your data stored in DynamoDB tables.\n\n```\n$ rm -rf ~/.dynein/\n```\n\nTo see verbose output for troubleshooting purpose, you can change log level by `RUST_LOG` environment variable. For example:\n\n```\n$ RUST_LOG=debug RUST_BACKTRACE=1 dy scan --table your_table\n```\n\n## Ideas for future works\n\n- `dy admin plan` \u0026 `dy admin apply` commands to manage tables through CloudFormation.\n  - These subcommand names are inspired by [HashiCorp's Terraform](https://www.terraform.io/).\n- Linux's `top` -like experience to monitor table status. e.g. `dy top tables`\n  - inspired by `kubectl top nodes`\n  - implementation:  (CloudWatch metrics such as Consumed WCU/RCU, SuccessfulRequestLatency, ReplicationLatency for GT etc)\n- Shell (bash/zsh) completion\n- Retrieving control plane APIs, integrated with CloudTrail\n- `dy logs` command to retrieving data plane API logs via DynamoDB Streams (write APIs only)\n  -  `tail -f` -ish usability. e.g. `dy logs -f mytable`\n- `truncate` command to delete all data in a table\n- Support Transaction APIs (TransactGetItems, TransactWriteItems)\n- simple load testing. e.g. `dy load --tps 100`\n- import/export tool supports LTSV, TSV\n- PITR configuration enable/disable (UpdateContinuousBackups) and exporting/restoring tables ([ExportTableToPointInTime](https://aws.amazon.com/blogs/aws/new-export-amazon-dynamodb-table-data-to-data-lake-amazon-s3/), RestoreTableToPointInTime)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawslabs%2Fdynein","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawslabs%2Fdynein","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawslabs%2Fdynein/lists"}