Me gustaría replicar algunas tablas de dynamodb, solo de esquema, en mi entorno local con fines de prueba. Primero he probado:

aws dynamodb describe-table --table-name Foo > FooTable.json

Pero es obvio que el esquema de salida no cumple con el esquema de entrada del create-tablecomando:

aws dynamodb create-table --cli-input-json file://FooTable.json --endpoint=http://localhost:8000

Lo que estoy tratando de evitar es generar docenas de esqueletos aws dynamodb create-table --generate-cli-skeletony llenarlos manualmente :/

¿Hay alguna manera de obtener el esquema de la tabla en un formato que sea "útil" para la recreación? Me parece increíble que no haya una forma sencilla de hacerlo a través de la interfaz gráfica web o la línea de comandos estándar de aws, después de escuchar lo "bueno" que fue su servicio.

Logré hacer un volcado completo y "restaurar" usando bchew/dynamodump :

1
git clone git@github.com:bchew/dynamodump.git

Observe la --schemaOnlyopción en la documentación https://github.com/bchew/dynamodump . El comando era:

1
./dynamodump.py -m backup --schemaOnly --region foo-region --host localhost --srcTable '*' --port 8000 --accessKey fooKey --secretKey barKey

Luego, puede usar el -m restoremodo para volver a colocar los datos o el esquema en un dynamodb local o donde lo desee 🙂

Dicho esto, todavía me parece increíble lo mala que es la cadena de herramientas de amazon dynamodb. Vamos chicos.

DynamoDB es una base de datos NoSQL que, con la excepción de la clave principal y los índices secundarios, no tiene un esquema. Puede notar en la tabla de descripción que solo muestra las claves y los índices, no otras columnas.

Por lo general, escribo código para crear la tabla y las claves en algún tipo de código  inicialización y luego empiezo a usar la tabla. No hará daño si la mesa ya está allí. Más tarde, si trato de insertar datos y la "columna" no existe, no importa, ya que DynamoDB la creará automáticamente.

Si necesita exportar los datos, existen herramientas para eso que le permitirán exportar (y algunas también permiten importar) desde DynamoDB.

Esto toma aws dynamodb describe-tablela salida y la transforma en el formato de entrada de aws dynamodb create-table --cli-input-json:

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11
AWS_PROFILE=xyz aws dynamodb describe-table --table-name MyTable > mytable_full.json
# Pull out just what is minimally needed for table-creation:
#
#  TableName
#  KeySchema
#  AttributeDefinitions (must only contain attributes used in keys)
#  Global/Local Secondary Indexes
#  Defaults BillingMode to PAY_PER_REQUEST
#   (any provisioning can be set up manually based on load)
jq <mytable_full.json '.Table | {TableName, KeySchema, AttributeDefinitions} + (try {LocalSecondaryIndexes: [ .LocalSecondaryIndexes[] | {IndexName, KeySchema, Projection} ]} // {}) + (try {GlobalSecondaryIndexes: [ .GlobalSecondaryIndexes[] | {IndexName, KeySchema, Projection} ]} // {}) + {BillingMode: "PAY_PER_REQUEST"}' ​>mytable.json
AWS_PROFILE=xyz aws dynamodb create-table --cli-input-json file://mytable.json

También puede pegar el json en python (la sintaxis de dict de python coincide estrechamente con json), por ejemplo

1 
2 
3 
4 
5 
6 
7 
8 
9
import boto3
dynamodb = boto3.resource("dynamodb")
tabledef = {
    "TableName": "MyTable",
    "KeySchema": [
...
}
table = dynamodb.create_table(**tabledef)
print("Table status: ", table.table_status)

Referencias:

https://docs.aws.amazon.com/cli/latest/reference/dynamodb/describe-table.html
https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html
https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html#creating-a-new -mesa

Aquí hay una versión que usa C#, AWS CLI y Newtonsoft JSON en Windows. Comience ejecutando este comando: –

1
aws dynamodb describe-table --table-name TheTable --profile SourceAWSCredsProfile > TheTable.json

Recoja el archivo, deserialice y serialice a la --cli-input-jsonclase amiga: –

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13
TableContainer tableContainer;
string sourceFile = "TheTable.json";
string destFile = "TheTable.cli-input.json";
using (StreamReader file = File.OpenText(sourceFile))
{
    JsonSerializer serializer = new JsonSerializer();
    tableContainer = (TableContainer)serializer.Deserialize(file, typeof(TableContainer));
}
File.WriteAllText(destFile, JsonConvert.SerializeObject(tableContainer.Table, Formatting.Indented, new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore
    }
));

Ahora ejecute este comando para importar la definición de la tabla: –

1
aws dynamodb create-table --cli-input-json file://TheTable.cli-input.json --profile DestinationAWSCredsProfile

La definición de la clase TableContainer se encuentra a continuación. La ausencia de ciertas propiedades limpia todo lo que el --cli-input-jsonparámetro no necesita. Puede recrear esta clase en cualquier momento ejecutando: –

1
aws dynamodb create-table --generate-cli-skeleton

Luego copie y pegue la salida en un nuevo archivo de clase, utilizando la Paste Special... Paste JSON as Classesfunción muy útil en Visual Studio.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
40 44 
4 
75 
5 _ _ 51 52 53 54 55 56 57










58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86
public class TableContainer
{
    public DynamoTableCLIJSON Table { get; set; }
}
public class DynamoTableCLIJSON
{
    public Attributedefinition[] AttributeDefinitions { get; set; }
    public string TableName { get; set; }
    public Keyschema[] KeySchema { get; set; }
    public Localsecondaryindex[] LocalSecondaryIndexes { get; set; }
    public Globalsecondaryindex[] GlobalSecondaryIndexes { get; set; }
    public string BillingMode { get; set; }
    public Provisionedthroughput ProvisionedThroughput { get; set; }
    public Streamspecification StreamSpecification { get; set; }
    public Ssespecification SSESpecification { get; set; }
    public Tag[] Tags { get; set; }
}
public class Provisionedthroughput
{
    public int ReadCapacityUnits { get; set; }
    public int WriteCapacityUnits { get; set; }
}
public class Streamspecification
{
    public bool StreamEnabled { get; set; }
    public string StreamViewType { get; set; }
}
public class Ssespecification
{
    public bool Enabled { get; set; }
    public string SSEType { get; set; }
    public string KMSMasterKeyId { get; set; }
}
public class Attributedefinition
{
    public string AttributeName { get; set; }
    public string AttributeType { get; set; }
}
public class Keyschema
{
    public string AttributeName { get; set; }
    public string KeyType { get; set; }
}
public class Localsecondaryindex
{
    public string IndexName { get; set; }
    public Keyschema1[] KeySchema { get; set; }
    public Projection Projection { get; set; }
}
public class Projection
{
    public string ProjectionType { get; set; }
    public string[] NonKeyAttributes { get; set; }
}
public class Keyschema1
{
    public string AttributeName { get; set; }
    public string KeyType { get; set; }
}
public class Globalsecondaryindex
{
    public string IndexName { get; set; }
    public Keyschema2[] KeySchema { get; set; }
    public Projection1 Projection { get; set; }
    public Provisionedthroughput1 ProvisionedThroughput { get; set; }
}
public class Projection1
{
    public string ProjectionType { get; set; }
    public string[] NonKeyAttributes { get; set; }
}
public class Provisionedthroughput1
{
    public int ReadCapacityUnits { get; set; }
    public int WriteCapacityUnits { get; set; }
}
public class Keyschema2
{
    public string AttributeName { get; set; }
    public string KeyType { get; set; }
}
public class Tag
{
    public string Key { get; set; }
    public string Value { get; set; }
}