Dynamoose: Won't create table with ddb local

Created on 21 Mar 2019  路  6Comments  路  Source: dynamoose/dynamoose

Summary:

I am unable to get dynamoose to create tables when using DynamoDB local, however, if I create the table via the aws command dynamoose will read/write from the table.

This code works without issue when pointing at the "real" aws ddb service.

Code sample:

Schema

export const ConfigItemSchema = new dynamoose.Schema(
  {
    ownerId: {
      rangeKey: true,
      type: String,
      required: true,
      default: "SYSTEM"
    },
    key: { hashKey: true, type: String, required: true },
    value: { type: String }
  },
  { throughput: "ON_DEMAND", timestamps: true }
);

Model

export const ConfigItem = dynamoose.model(
  `DevConfigItems`,
  ConfigItemSchema
);

General

 const dynamooseDefaults = {
    create: true,
    prefix: "Dev"
    suffix: "",
    waitForActive: true, // Wait for table to be created
    waitForActiveTimeout: 180000 // 3 minutes,
  };

const dbUrl = "http://localhost:8000";
  dynamoose.AWS.config.update({
    dynamodb: {
      endpoint: dbUrl
    },
    region: "us-east-1",
  });

  log.info("Initializing Dynamoose with defaults: ", dynamooseDefaults);
  dynamoose.setDefaults(dynamooseDefaults);

  log.info(`setting dynamodb url to ${dbUrl}`);
  dynamoose.local(dbUrl);

  await ConfigItem.scan({}).exec();

Current output and behavior:

The last log entry repeats over and over for 180 seconds (waitForActiveTimeout value) and the table is not created. It doesn't matter how high I set the timeout value, it never succeeds.

If I create the table with the following command, then start my node app, it works without issue.

aws dynamodb create-table --table-name "$1ConfigItems" --attribute-definitions AttributeName=ownerId,AttributeType=S AttributeName=key,AttributeType=S --key-schema AttributeName=key,KeyType=HASH AttributeName=ownerId,KeyType=RANGE --billing-mode PAY_PER_REQUEST --endpoint-url http://localhost:8000

api_1            | 2019-03-21T19:44:35.334Z dynamoose:schema Creating Schema { ownerId:
api_1            |    { rangeKey: true,
api_1            |      type: [Function: String],
api_1            |      required: true,
api_1            |      default: 'SYSTEM' },
api_1            |   key: { hashKey: true, type: [Function: String], required: true },
api_1            |   value: { type: [Function: String] } }
api_1            | 2019-03-21T19:44:35.337Z dynamoose:schema Adding Attribute to Schema (ownerId) { ownerId:
api_1            |    { rangeKey: true,
api_1            |      type: [Function: String],
api_1            |      required: true,
api_1            |      default: 'SYSTEM' },
api_1            |   key: { hashKey: true, type: [Function: String], required: true },
api_1            |   value: { type: [Function: String] },
api_1            |   createdAt: { type: [Function: Date], default: [Function: now] },
api_1            |   updatedAt:
api_1            |    { type: [Function: Date],
api_1            |      default: [Function: now],
api_1            |      set: [Function] } }
api_1            | 2019-03-21T19:44:35.337Z dynamoose:attribute create: {"tree":{},"methods":{},"statics":{},"virtuals":{},"options":{"throughput":"ON_DEMAND","timestamps":true},"throughput":"ON_DEMAND","timestamps":{"createdAt":"createdAt","updatedAt":"updatedAt"},"useDocumentTypes":true,"useNativeBooleans":true,"attributes":{},"indexes":{"local":{},"global":{}}} : "ownerId" : {"rangeKey":true,"required":true,"default":"SYSTEM"}
api_1            | 2019-03-21T19:44:35.338Z dynamoose:attribute Creating attribute ownerId { rangeKey: true, type: [Function: String], required: true, default: 'SYSTEM' }
api_1            | 2019-03-21T19:44:35.339Z dynamoose:schema Adding Attribute to Schema (key) { ownerId:
api_1            |    { rangeKey: true,
api_1            |      type: [Function: String],
api_1            |      required: true,
api_1            |      default: 'SYSTEM' },
api_1            |   key: { hashKey: true, type: [Function: String], required: true },
api_1            |   value: { type: [Function: String] },
api_1            |   createdAt: { type: [Function: Date], default: [Function: now] },
api_1            |   updatedAt:
api_1            |    { type: [Function: Date],
api_1            |      default: [Function: now],
api_1            |      set: [Function] } }
api_1            | 2019-03-21T19:44:35.339Z dynamoose:attribute create: [Circular] : "key" : {"hashKey":true,"required":true}
api_1            | 2019-03-21T19:44:35.339Z dynamoose:attribute Creating attribute key { hashKey: true, type: [Function: String], required: true }
api_1            | 2019-03-21T19:44:35.339Z dynamoose:schema Adding Attribute to Schema (value) { ownerId:
api_1            |    { rangeKey: true,
api_1            |      type: [Function: String],
api_1            |      required: true,
api_1            |      default: 'SYSTEM' },
api_1            |   key: { hashKey: true, type: [Function: String], required: true },
api_1            |   value: { type: [Function: String] },
api_1            |   createdAt: { type: [Function: Date], default: [Function: now] },
api_1            |   updatedAt:
api_1            |    { type: [Function: Date],
api_1            |      default: [Function: now],
api_1            |      set: [Function] } }
api_1            | 2019-03-21T19:44:35.339Z dynamoose:attribute create: [Circular] : "value" : {}
api_1            | 2019-03-21T19:44:35.339Z dynamoose:attribute Creating attribute value { type: [Function: String] }
api_1            | 2019-03-21T19:44:35.339Z dynamoose:schema Adding Attribute to Schema (createdAt) { ownerId:
api_1            |    { rangeKey: true,
api_1            |      type: [Function: String],
api_1            |      required: true,
api_1            |      default: 'SYSTEM' },
api_1            |   key: { hashKey: true, type: [Function: String], required: true },
api_1            |   value: { type: [Function: String] },
api_1            |   createdAt: { type: [Function: Date], default: [Function: now] },
api_1            |   updatedAt:
api_1            |    { type: [Function: Date],
api_1            |      default: [Function: now],
api_1            |      set: [Function] } }
api_1            | 2019-03-21T19:44:35.340Z dynamoose:attribute create: [Circular] : "createdAt" : {}
api_1            | 2019-03-21T19:44:35.340Z dynamoose:attribute Creating attribute createdAt { type: [Function: Date], default: [Function: now] }
api_1            | 2019-03-21T19:44:35.340Z dynamoose:schema Adding Attribute to Schema (updatedAt) { ownerId:
api_1            |    { rangeKey: true,
api_1            |      type: [Function: String],
api_1            |      required: true,
api_1            |      default: 'SYSTEM' },
api_1            |   key: { hashKey: true, type: [Function: String], required: true },
api_1            |   value: { type: [Function: String] },
api_1            |   createdAt: { type: [Function: Date], default: [Function: now] },
api_1            |   updatedAt:
api_1            |    { type: [Function: Date],
api_1            |      default: [Function: now],
api_1            |      set: [Function] } }
api_1            | 2019-03-21T19:44:35.340Z dynamoose:attribute create: [Circular] : "updatedAt" : {}
api_1            | 2019-03-21T19:44:35.340Z dynamoose:attribute Creating attribute updatedAt { type: [Function: Date], default: [Function: now], set: [Function] }
api_1            | 2019-03-21T19:44:35.354Z dynamoose Looking up model DevConfigItems
api_1            | 2019-03-21T19:44:35.355Z dynamoose:model compiling NewModel DevConfigItems
api_1            | 2019-03-21T19:44:35.355Z dynamoose:table new Table (DevConfigItems) Schema {
api_1            |   tree: {},
api_1            |   methods: {},
api_1            |   statics: {},
api_1            |   virtuals: {},
api_1            |   options: { throughput: 'ON_DEMAND', timestamps: true },
api_1            |   throughput: 'ON_DEMAND',
api_1            |   timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' },
api_1            |   useDocumentTypes: true,
api_1            |   useNativeBooleans: true,
api_1            |   attributeFromDynamo: undefined,
api_1            |   attributeToDynamo: undefined,
api_1            |   attributes:
api_1            |    { ownerId:
api_1            |       Attribute {
api_1            |         options: [Object],
api_1            |         schema: [Circular],
api_1            |         name: 'ownerId',
api_1            |         isSet: false,
api_1            |         type: [Object],
api_1            |         attributes: {},
api_1            |         default: [Function],
api_1            |         required: true },
api_1            |      key:
api_1            |       Attribute {
api_1            |         options: [Object],
api_1            |         schema: [Circular],
api_1            |         name: 'key',
api_1            |         isSet: false,
api_1            |         type: [Object],
api_1            |         attributes: {},
api_1            |         required: true },
api_1            |      value:
api_1            |       Attribute {
api_1            |         options: [Object],
api_1            |         schema: [Circular],
api_1            |         name: 'value',
api_1            |         isSet: false,
api_1            |         type: [Object],
api_1            |         attributes: {},
api_1            |         required: undefined },
api_1            |      createdAt:
api_1            |       Attribute {
api_1            |         options: [Object],
api_1            |         schema: [Circular],
api_1            |         name: 'createdAt',
api_1            |         isSet: false,
api_1            |         type: [Object],
api_1            |         attributes: {},
api_1            |         default: [Function: now],
api_1            |         required: undefined },
api_1            |      updatedAt:
api_1            |       Attribute {
api_1            |         options: [Object],
api_1            |         schema: [Circular],
api_1            |         name: 'updatedAt',
api_1            |         isSet: false,
api_1            |         type: [Object],
api_1            |         attributes: {},
api_1            |         default: [Function: now],
api_1            |         required: undefined,
api_1            |         set: [Function] } },
api_1            |   indexes: { local: {}, global: {} },
api_1            |   rangeKey:
api_1            |    Attribute {
api_1            |      options:
api_1            |       { rangeKey: true,
api_1            |         type: [Function: String],
api_1            |         required: true,
api_1            |         default: 'SYSTEM' },
api_1            |      schema: [Circular],
api_1            |      name: 'ownerId',
api_1            |      isSet: false,
api_1            |      type: { name: 'string', dynamo: 'S' },
api_1            |      attributes: {},
api_1            |      default: [Function],
api_1            |      required: true },
api_1            |   hashKey:
api_1            |    Attribute {
api_1            |      options: { hashKey: true, type: [Function: String], required: true },
api_1            |      schema: [Circular],
api_1            |      name: 'key',
api_1            |      isSet: false,
api_1            |      type: { name: 'string', dynamo: 'S' },
api_1            |      attributes: {},
api_1            |      required: true } }
api_1            | 2019-03-21T19:44:35.356Z dynamoose:model applying methods
api_1            | 2019-03-21T19:44:35.356Z dynamoose:model applying statics
api_1            | 2019-03-21T19:44:35.356Z dynamoose:table initializing table, DevConfigItems, {"create":true,"waitForActive":true,"waitForActiveTimeout":180000,"prefix":"","suffix":""}
api_1            | 2019-03-21T19:44:35.357Z dynamoose Getting default DynamoDB
api_1            | info: [api:loaders/dynamooseLoader] setting dynamodb url to http://localhost:8000
api_1            | 2019-03-21T19:44:43.491Z dynamoose Setting DynamoDB to local (http://localhost:8000)
api_1            | info: [api:loaders/dynamooseLoader] Initializing Dynamoose with defaults:  create=true, prefix=Dev, suffix=, waitForActive=true, waitForActiveTimeout=20000
api_1            | 2019-03-21T19:44:43.493Z dynamoose:scan exec scan for  undefined
api_1            | 2019-03-21T19:44:43.493Z dynamoose:table Waiting for Active table, DevConfigItems, {"create":true,"waitForActive":true,"waitForActiveTimeout":180000,"prefix":"","suffix":""}
api_1            | 2019-03-21T19:44:43.494Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.504Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.515Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.526Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.537Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.547Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.557Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.577Z dynamoose:table table exist -- initialization done
api_1            | 2019-03-21T19:44:43.578Z dynamoose:table Using PAY_PER_REQUEST BillingMode for DevConfigItems table creation
api_1            | 2019-03-21T19:44:43.578Z dynamoose:table Creating table local indexes {}
api_1            | 2019-03-21T19:44:43.578Z dynamoose:table compareIndexes
api_1            | 2019-03-21T19:44:43.579Z dynamoose:table {
api_1            |   "delete": [],
api_1            |   "create": []
api_1            | }
api_1            | 2019-03-21T19:44:43.579Z dynamoose:table Waiting for Active table, DevConfigItems, {"create":true,"waitForActive":true,"waitForActiveTimeout":180000,"prefix":"","suffix":""}
api_1            | 2019-03-21T19:44:43.579Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:43.589Z dynamoose:table Waiting...
api_1            | 2019-03-21T19:44:44.117Z dynamoose:table error describing table { ResourceNotFoundException: Cannot do operations on a non-existent table
api_1            |     at Request.extractError (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/protocol/json.js:51:27)
api_1            |     at Request.callListeners (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
api_1            |     at Request.emit (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
api_1            |     at Request.emit (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:683:14)
api_1            |     at Request.transition (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:22:10)
api_1            |     at AcceptorStateMachine.runTo (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/state_machine.js:14:12)
api_1            |     at /usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/state_machine.js:26:10
api_1            |     at Request.<anonymous> (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:38:9)
api_1            |     at Request.<anonymous> (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:685:12)
api_1            |     at Request.callListeners (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
api_1            |     at Request.emit (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
api_1            |     at Request.emit (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:683:14)
api_1            |     at Request.transition (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:22:10)
api_1            |     at AcceptorStateMachine.runTo (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/state_machine.js:14:12)
api_1            |     at /usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/state_machine.js:26:10
api_1            |     at Request.<anonymous> (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:38:9)
api_1            |     at Request.<anonymous> (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/request.js:685:12)
api_1            |     at Request.callListeners (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
api_1            |     at callNextListener (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/sequential_executor.js:96:12)
api_1            |     at IncomingMessage.onEnd (/usr/src/api/node_modules/dynamoose/node_modules/aws-sdk/lib/event_listeners.js:299:13)
api_1            |     at emitNone (events.js:111:20)
api_1            |     at IncomingMessage.emit (events.js:208:7)
api_1            |     at endReadableNT (_stream_readable.js:1064:12)
api_1            |     at _combinedTickCallback (internal/process/next_tick.js:138:11)
api_1            |     at process._tickDomainCallback (internal/process/next_tick.js:218:9)
api_1            |   message: 'Cannot do operations on a non-existent table',
api_1            |   code: 'ResourceNotFoundException',
api_1            |   time: 2019-03-21T19:44:44.116Z,
api_1            |   requestId: 'f59787f3-89e3-4c7f-98f1-35c00ec2bb33',
api_1            |   statusCode: 400,
api_1            |   retryable: false,
api_1            |   retryDelay: 4.737243667071478 }

Expected output and behavior:

I expect the table to ddb local table to be created

Environment:

Operating System: debian
Operating System Version: jessie
Node.js version (node -v): 8.10
NPM version: (npm -v): 5.6.0
Dynamoose version: 1.7.2
Dynamoose Plugins: None

Dynamoose Plugins:

  • [ ] Yes, I believe that one or multiple 3rd party Dynamoose plugins are effecting this issue
  • [ ] No, I believe this issue is independent of any 3rd party Dynamoose plugins I'm using
  • [ ] Unknown, I'm unsure if Dynamoose plugins are effecting this issue
  • [x] I am not using any Dynamoose plugins

Type (select 1):

  • [x] Bug report
  • [ ] Feature suggestion
  • [ ] Question
  • [ ] Other suggestion
  • [ ] Something not listed here

Other:

  • [x] I have read through the Dynamoose documentation before posting this issue
  • [x] I have searched through the GitHub issues (including closed issues) and pull requests to ensure this issue has not already been raised before
  • [x] I have searched the internet and Stack Overflow to ensure this issue hasn't been raised or answered before
  • [x] I have tested the code provided and am confident it doesn't work as intended
  • [ ] I have ensured that all of my plugins that I'm using with Dynamoose are listed above
  • [x] I have filled out all fields above
  • [x] I am running the latest version of Dynamoose

Most helpful comment

Hi @mcalhoun am facing the same issue... did you manage to find a solution to this?

All 6 comments

@mcalhoun The only time I鈥檝e experienced this is when I had a race condition and it was trying to create the table twice. I鈥檓 also not sure why you are doing a process.exit. You also have a lot of environment variables and unique code you are using that is specific to your project. Please create a complete example that is easy for us to reproduce with the least amount of code required to reproduce the issue.

Hi Charlie,

With all due respect, I don't see how I can create a much more minimal example? I've defined the schema, the model, set dynamoose.AWS.config.update and then set dynamoose.setDefaults. After that I tried a table scan and then exit. That's the minimum code required to reproduce the issue I'm seeing.

And I'm not sure which environment variables you're referring to? The only env vars are for AWS credentials.

Thanks,
Matt

Hi @mcalhoun am facing the same issue... did you manage to find a solution to this?

@mcalhoun Oh I THINK I see the problem, could be wrong tho. Kinda gets back to the point of a complete reproducible minimal example.

In your general code, you use ConfigItem. Where are you defining that? I'm assuming at the top of that file. Your dynamoose.AWS.config.update and dynamoose.local function calls should always be the first interaction you have with Dynamoose.

So if that is the case, that is incorrect, because you are creating the schema and model before you setup Dynamoose with your configuration and all of that.

cc/ @sohailalam2

Thanks @fishcharlie This solved it for me, I had one require before initialization, it creates the Schema before dynamoose.local(...

Had the same problem and https://github.com/dynamoosejs/dynamoose/issues/606#issuecomment-479985620 solved it for me. Maybe we should explicitly add this to the docs, as I'm not seeing something that says anything close to Your dynamoose.AWS.config.update and dynamoose.local function calls should always be the first interaction you have with Dynamoose in the docs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MickL picture MickL  路  6Comments

mogwai picture mogwai  路  5Comments

brennhill picture brennhill  路  10Comments

chasevida picture chasevida  路  3Comments

AllanOricil picture AllanOricil  路  4Comments