API

AWS Credentials

There are three ways to specify AWS credentials:

  • .aws/credentials
  • Environment Variables
  • AWS.config

Dynamoose Object

var dynamoose = require('dynamoose');

dynamoose.model(name, schema, [options])

Compiles a new model or looks up an existing one. options is optional.

Default options:

{
  create: true, // Create table in DB, if it does not exist,
  update: false, // Update remote indexes if they do not match local index structure
  waitForActive: true, // Wait for table to be created before trying to use it
  waitForActiveTimeout: 180000, // wait 3 minutes for table to activate
  streamOptions: { // sets table stream options
    enabled: false, // sets if stream is enabled on the table
    type: undefined // sets the stream type (NEW_IMAGE | OLD_IMAGE | NEW_AND_OLD_IMAGES | KEYS_ONLY) (https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_StreamSpecification.html#DDB-Type-StreamSpecification-StreamViewType)
  },
  serverSideEncryption: false // Set SSESpecification.Enabled (server-side encryption) to true or false (default: true)
}

Basic example:

var Cat = dynamoose.model('Cat', { id: Number, name: String });

streamOptions: object (optional)

Indicates whether stream is enabled or disabled on the table and dictates which type of stream the table should have. This is passed into into the StreamSpecification option property when creating the table.

serverSideEncryption: boolean

Indicates whether server-side encryption is enabled (true) or disabled (false) on the table. This boolean will be passed into the SSESpecification.Enabled option property when creating the table. Currently (when feature was implemented) DynamoDB doesn’t support updating a table to add or remove server-side encryption, therefore this option will only be respected on creation of table, if table already exists in DynamoDB when using Dynamoose this value will be ignored.

var model = dynamoose.model('Cat', {...}, {
	streamOptions: {
      enabled: true,
      type: "NEW_AND_OLD_IMAGES"
    },
	serverSideEncryption: true
});

dynamoose.local(url)

Configure dynamoose to use a DynamoDB local for testing.

url defaults to ‘http://localhost:8000’

dynamoose.local();

dynamoose.ddb()

Configures and returns the AWS.DynamoDB object

dynamoose.AWS

AWS object for dynamoose. Used to configure AWS for dynamoose.

dynamoose.AWS.config.update({
  accessKeyId: 'AKID',
  secretAccessKey: 'SECRET',
  region: 'us-east-1'
});

dynamoose.setDDB

Function to set the DynamoDB object that Dynamoose uses.

var AWS = require('aws-sdk');
var dynamoDB = new AWS.dynamoDB();
dynamoose.setDDB(dynamoDB);

dynamoose.revertDDB

Function to revert the DynamoDB object that Dynamoose uses to the default.

dynamoose.revertDDB();

dynamoose.setDefaults(options)

Sets the default to be used when creating a model. Can be modified on a per model by passing options to .model().

Default options:

{
  create: true // Create table in DB if it does not exist
  prefix: '', // Default prefix for all DynamoDB tables
  suffix: '' // Default suffix for all DynamoDB tables
}

It is recommended that create be disabled for production environments.

dynamoose.setDefaults( { create: false });

dynamoose.Schema

The dynamoose Schema class, used to create new schema definitions. For example:

var appleSchema = new dynamoose.Schema({
  id: Number, 
  type: String
});

dynamoose.Table

Table class

AWS X-Ray Support

You can achieve Amazon Web Services X-Ray support using a configuration similar to the following.

var AWSXRay = require('aws-xray-sdk');
var dynamoose = require('dynamoose');
dynamoose.AWS = AWSXRay.captureAWS(require('aws-sdk'));

dynamoose.setDocumentClient(documentClient)

Sets the document client for DynamoDB. This can be used to integrate with Amazon Web Services DAX.

dynamoose.transaction(items[, options][, cb])

Allows you to run DynamoDB transactions. Accepts an array as the items parameter. You can pass in a RAW DynamoDB transaction object, or use the Dynamoose Model.transaction helper methods.

dynamoose.transaction([
  User.transaction.update({id: "user1"}, {$ADD: {balance: -100}}),
  Charge.transaction.create({userid: "user1", product: "product1", amount: 100, status: "successful"}),
  Product.transaction.update({id: "product1"}, {$ADD: {inventory: -1}}),
  Credit.transaction.delete({id: "credit1"}),
  {
    Delete: {
      Key: {
        id: {
          S: 'helloworld'
        }
      },
      TableName: 'MyOtherTable'
    }
  }
]).then(function (result) {
  console.log(result);
}).catch(function (err) {
  console.error(err);
});

If you use a custom RAW DynamoDB transaction object, you must have created a corresponding model in Dynamoose.

options properties:

  • type (string): The type of transaction Dynamoose will run. Can either be “get”, or “write”. By default if all of your items are of type “get”, it will default to “get”, otherwise, will default to “write”.

Schema

Schemas are used to define DynamoDB table attributes and their constraints.

Creating a new Schema

Schemas are created using new Schema(attrDefObj, options).

The first argument (attrDefObj) is an object containing attribute definitions. Keys of this object correspond to attributes in the resulting DynamoDB table. The values of these keys define constraints on those attributes (as well as a few handy features…). See Attribute Definitions for a more thorough description.

The second argument (options) defines options for the table that are beyond the scope of individual attributes. See Schema Options for more.

The following is an example of creating a new Schema:

var Schema = dynamoose.Schema;

var dogSchema = new Schema({
  ownerId: {
    type: Number,
    validate: function(v) { return v > 0; },
    hashKey: true
  },
  name: {
    type: String,
    rangeKey: true,
    index: true // name: nameLocalIndex, ProjectionType: ALL
  },
  race: {
     type: String,
     enum: ['Golden retriever', 'Beagle']
  },
  breed: {
    type: String,
    trim: true,
    required: true,
    index: {
      global: true,
      rangeKey: 'ownerId',
      name: 'BreedIndex',
      project: true, // ProjectionType: ALL
      throughput: 5 // read and write are both 5
    }
  },
  color: {
    lowercase: true,
    type: [String],
    default: ['Brown']
  },
  age: Number
},
{
  throughput: {read: 15, write: 5}
});

Attribute Types

Attribute Types define the domain of a particular attribute. For example, a name might be set to String or age to Number.

The following table describes valid Attribute Types, and their translation to DynamoDB types:

Attribute Type Resulting DynamoDB Type
String ‘S’
Number ‘N’
Boolean* ‘S’ or ‘BOOL’
Date ‘N’
Object* ‘S’ or ‘M’
Array* ‘S’ or ‘L’
Buffer ‘B’
[String] ‘SS’
[Number] ‘NS’
[Boolean] ‘SS’
[Date] ‘NS’
[Object] ‘SS’
[Array] ‘SS’

* Use useNativeBooleans and useDocumentTypes to change DynamoDB type

Attribute Definitions

Attribute definitions define constraints on a particular attribute specified in a Schema. Attribute definitions may be an object type (see Attribute Types) or an object with the following options:

type: AttributeType required

Required for all attribute definitions. Defines the attribute type. See Attribute Types.

hashKey: boolean

Sets the attribute as the table’s hash key. If this option isn’t specified in a schema, then the first attribute is defined as the hash key.

rangeKey: boolean

Sets the attribute as the table’s range key.

required: boolean

Sets the attribute as a ‘required’ attribute. Required attributes must not be saved as undefined or null, or an error will be thrown.

index: boolean | object | [objects]

Defines the attribute as a local or global secondary index. Index can either be true, an index definition object or and array of index definition objects. The array is used define multiple indexes for a single attribute. The index definition object can contain the following keys:

  • name: ‘string’ - Name of index (Default is attribute.name + (global ? 'GlobalIndex' : 'LocalIndex')).
  • global: boolean - Set the index to be a global secondary index. Attribute will be the hash key for the Index.
  • rangeKey: ‘string’ - The range key for a global secondary index.
  • project: boolean | [‘string’, …] - Sets the attributes to be projected for the index. true projects all attributes, false projects only the key attributes, and [‘string’, …] projects the attributes listed. Default is true.
  • throughput: number | {read: number, write: number} - Sets the throughput for the global secondary index.

default: function | value

Applies a default to the attribute’s value when saving, if the values is null or undefined.

If default is a function, the function is called with the current model instance, and the response is assigned to the attribute’s value.

If it is a value, the value is simply assigned.

function(model) {
    return model.name +'_'+ model.category;
}

enum: Array of strings

Force value to be one of the enumeration values.

forceDefault: boolean

(default: false) Will force the default value to always be applied to the attribute event if it already set. This is good for populating data that will be used as sort or secondary indexes.

validate: function, regular expression, or value

Validation required before for saving.

If validate is a function, the function is used to validate the attribute’s value. The function must have the signature:

function(value, model) {
  if(valid)
    return true;
  else
    return false;
}

If it is a RegExp, it is compared using RegExp.test(value).

If it is a value, it is compared with ===.

set: function

Adds a setter function that will be used to transform the value before writing to the DB.

get: function

Adds a getter function that will be used to transform the value returned from the DB, fired only if there is a value returned from the DB.

toDynamo: function

Adds a setter function that will directly set the value to the DB. This skips all type management and parsing normally provided by options.set.

fromDynamo: function

Adds a getter function that will be used to transform the value directly returned from the DB. This skips all type management and parsing normally provided by options.get.

trim: boolean

Trim whitespace from string when saving to DB.

lowercase: boolean

Convert to lowercase when saving to DB.

uppercase: boolean

Convert to uppercase when saving to DB.

Options

throughput: number string | {read: number, write: number}

Sets the throughput of the DynamoDB table on creation. The value can either be a number or an object with the keys read and write (for example: {read: 5, write: 2}). If it is a number, both read and write are configured to that number. If it is omitted, the read and write values will be set to 1. Throughput will only be respected on table creation, and will not update the throughput of an existing table.

If this property is set to "ON_DEMAND" the table will be created using PAY_PER_REQUEST BillingMode.

var schema = new Schema({...}, {
  throughput: 5
});
var schema = new Schema({...}, {
  throughput: {
    read: 5,
    write: 2
  }
});

useNativeBooleans: boolean

Store Boolean values as Boolean (‘BOOL’) in DynamoDB. Default to true (i.e store as DynamoDB boolean).

var schema = new Schema({...}, {
  useNativeBooleans: true
});

useDocumentTypes: boolean

Store Objects and Arrays as Maps (‘M’) and Lists (‘L’) types in DynamoDB. Defaults to true (i.e. store as DynamoDB maps and lists).

var schema = new Schema({...}, {
  useDocumentTypes: true
});

timestamps: boolean | {createdAt: string, updatedAt: string}

Defines that schema must contain fields to control creation and last update timestamps. If it is set to true, this fields will be createdAt for creation date and updatedAt for last update. for example:

var schema = new Schema({...}, {
  throughput: 5,
  timestamps: true
});

You can specify the names that the fields will use, like in the following example:

var schema = new Schema({...}, {
  throughput: 5,
  timestamps: {
    createdAt: 'creationDate',
    updatedAt: 'lastUpdateDate'
  }
});

expires: number | {ttl: number, attribute: string, returnExpiredItems: boolean, defaultExpires: function}

Defines that schema must contain an expires attribute. This field is configured in DynamoDB as the TTL attribute. If set to a number, an attribute named “expires” will be added to the schema. The default value of the attribute will be the current time plus the expires value, unless an optional defaultExpires property is passed in. The expires value is in seconds.

The attribute will be a standard javascript Date in the object, and will be stored as number (‘N’) in the DyanmoDB table. The stored number is in seconds. More information about DynamoDB TTL

var schema = new Schema({...}, {
  expires: 7*24*60*60 // 1 week in seconds
});

You can specify the attribute name by passing an object:

var schema = new Schema({...}, {
  expires: {
    ttl: 7*24*60*60, // 1 week in seconds
    attribute: 'ttl', // ttl will be used as the attribute name
    returnExpiredItems: true, // if expired items will be returned or not (default: true)
    defaultExpires: function () { // optional, will default to `ttl` if not defined, this function is mainly used to allow the expires to be set to null or undefined, without resetting to the normal default
      return null;
    }
  }
});

saveUnknown: boolean or array

Specifies that attributes not defined in the schema will be saved and retrieved. This defaults to false.

var schema = new Schema({...}, {
  saveUnknown: true
});

If an array is passed in, only attributes that are in the array passed in will be saved and retrieved.

var schema = new Schema({...}, {
  saveUnknown: ['name', 'age'] // only `name` and `age` unknown attributes will be saved and retrieved from DynamoDB
});

attributeToDynamo: function

A function that accepts name, json, model, defaultFormatter, options.

This will override attribute formatting for all attributes. Whatever is returned by the function will be sent directly to the DB.

var schema = new Schema({...}, {
  attributeToDynamo: function(name, json, model, defaultFormatter, options) {
    switch(name) {
        case 'specialAttribute':
            return specialFormatter(json);
        default:
            return specialFormatter(json);
    }
  }
});

attributeFromDynamo: function

A function that accepts name, json, fallback.

This will override attribute parsing for all attributes. Whatever is returned by the function will be passed directly to the model instance.

var schema = new Schema({...}, {
  attributeFromDynamo: function(name, json, defaultParser) {
    switch(name) {
        case 'specialAttribute':
            return specialParser(json);
        default:
            return defaultParser(json);
    }
  }
});

Methods

You can add custom methods to your Schema. Model methods can be accessed via this.model(modelName).

var Schema = dynamoose.Schema;

var dogSchema = new Schema({
  ownerId: {
    type: Number,
    validate: function(v) { return v > 0; },
    hashKey: true
  },
  name: {
    type: String,
    rangeKey: true,
    index: true // name: nameLocalIndex, ProjectionType: ALL
  },
  friends: {
    type: [String],
    default: [],
  }
});

dogSchema.method('becomeFriends', function (otherDog) {
  this.friends = this.friends || [];
  otherDog.friends = otherDog.friends || [];
  this.friends.push(otherDog.name);
  otherDog.friends.push(this.name);
  this.model('Dog').batchPut([this, otherDog]);
});

var Dog = dynamoose.model('Dog', dogSchema);
var dog1 = new Dog({ ownerId: 137, name: 'Snuffles' });
var dog2 = new Dog({ ownerId: 138, name: 'Bill'});
dog1.becomeFriends(dog2);

Static Methods

Can be accessed from the compiled Schema, similar to how scan() and query() are called. this will refer to the compiled schema within the definition of the function.


// Construction:
var ModelSchema = new Schema({...})

ModelSchema.statics.getAll = async function(cb){
  let results = await this.scan().exec()
  while (results.lastKey){
      results = await this.scan().startKey(results.startKey).exec()
  }
  return results
}

var Model = dynamoose.model('Model', ModelSchema)

// Using:
Model.getAll(function(err, models)=>{
    models.forEach(function(model){
      console.log(model)
    })
})

Instance Methods

Can be accessed from a newly created model. this will refer to the instace of the model within the definition of the function.


// Construction:
var ModelSchema = new Schema({
  name:String
})

ModelSchema.methods.setName = function(name) {
  this.name = name
}

var Model = dynamoose.model('Model', ModelSchema)

// Using:
var batman = new Model({name: "Bruce"})
batman.setName("Bob")

Model

Create Model From Schema

var Dog = dynamoose.model('Dog', dogSchema);

new Model(object)

Creates a new instance of the model. Object keys are assigned to the new model.

var odie = new Dog({
  ownerId: 4,
  name: 'Odie',
  breed: 'Beagle',
  color: ['Tan'],
  cartoon: true
});

model.put(options, callback) & model.save(options, callback)

Puts the item in the DynamoDB table. Will overwrite the item.

odie.save(function (err) {
  if(err) { return console.log(err); }
  console.log('Ta-da!');
});

odie.save({
    condition: '#o = :ownerId',
    conditionNames: { o: 'ownerId' },
    conditionValues: { ownerId: 4 }
  }, function (err) {
  if(err) { return console.log(err); }
  console.log('Ta-da!');
});

Options:

  • overwrite: should overwrite the existing item in DynamoDB (default: true)
  • updateExpires: should update the expires timestamp if exists (default: false)
  • updateTimestamps: should update the updatedAt timestamp if exists (default: true)
  • returnRequest: should not make request to DynamoDB and resolve with request (default: false)

Model.batchPut(items, options, callback)

Puts multiple items in the table. Will overwrite existing items.

Dog.batchPut([
  {
    ownerId: 2,
    name: 'Princes',
    breed: 'Jack Russell Terrier',
    color: ['White', 'Brown'],
    cartoon: true
  },
  {
    ownerId: 3,
    name: 'Toto',
    breed: 'Terrier',
    color: ['Brown'],
    cartoon: false
  },
  {
    ownerId: 4,
    name: 'Odie',
    breed: 'Beagle',
    color: ['Tan'],
    cartoon: true
  },
  {
    ownerId: 5,
    name: 'Lassie',
    breed: 'Beagle',
    color: ['Tan'],
    cartoon: false
  }], function (err, dogs) {
    if (err) { return console.log(err); }
    console.log('Ta-da!');
  });

Options

overwrite: boolean

Overwrite existing item. Defaults to true.

updateExpires: boolean

Update the expires timestamp if exists. Defaults to false.

updateTimestamps: boolean

Should update the updatedAt timestamp if exists. Defaults to false.

condition: string

An expression for a conditional update. See the AWS documentation for more information about condition expressions.

conditionNames: object

A map of name substitutions for the condition expression.

conditionValues: object

A map of values for the condition expression. Note that in order for automatic object conversion to work, the keys in this object must match schema attribute names.

Model.create(object, options, callback)

Creates a new instance of the model and save the item in the table.

Dog.create({
  ownerId: 4,
  name: 'Odie',
  breed: 'Beagle',
  color: ['Tan'],
  cartoon: true
}, function(err, odie) {
  if(err) { return console.log(err); }
  console.log('Odie is a ' + odie.breed);
});

You can set options.returnRequest to true, to resolve the get request instead of making the request.

Model.get(key, options, callback)

Gets an item from the table.

Dog.get({ownerId: 4, name: 'Odie'}, function(err, odie) {
  if(err) { return console.log(err); }
  console.log('Odie is a ' + odie.breed);
});

You can set options.returnRequest to true, to resolve the get request instead of making the request.

Model.populate(options)

Populates paths from an item from the table.

(Only promise mode yet)

Dog = dynamoose.model('Dog', {
    id: {
      type:  Number
    },
    name: {
      type: String
    },
    parent: Number
  })

/*
Available dogs
{ id: 1, name: 'Odie'}
{ id: 2, name: 'Rex', parent: 1 }
{ id: 3, name: 'Fox', parent: 2 }
*/

Dog.get(3)
  .then(function(dog) {
    return dog.populate({
      path: 'parent',
      model: 'Dog',
      populate: {
        path: 'parent',
        model: 'Dog'
      }
    });
  })
  .then(function(dog) {
    console.log(dog);
    /*
    {
      id: 3,
      name: 'Fox',
      parent: {
        id: 2,
        name: 'Rex',
        parent: {
          id: 1,
          name: 'Odie'
        }
      }
    }
    */
  });


Dog.scan().exec()
  .then(function(dogs) {
    return Promise.all(dogs.map(function(dog) {
      return dog.populate({
        path: 'parent',
        model: 'Dog'
      });
    }));
  })
  .then(function(dogs) {
    console.log(dogs);
  });

Populate with range and hash key

If the object to populate has both a range and hash key, you must store both in the attribute.

const CatWithOwner = dynamoose.model('CatWithOwner',
  {
    id: {
      type:  Number
    },
    name: {
      type: String
    },
    owner: {
      name: String,
      address: String
    }
  }
);

const Owner = dynamoose.model('Owner',
  {
    name: {
      type: String,
      hashKey: true
    },
    address: {
      type: String,
      rangeKey: true
    },
    phoneNumber: String
  }
);

var owner = new Owner({
  name: 'Owner',
  address: '123 A Street',
  phoneNumber: '2345551212'
});

var kittenWithOwner = new CatWithOwner({
  id: 100,
  name: 'Owned',
  owner: {
    name: owner.name,
    address: owner.address
  }
});

CatWithOwner.get(100)
.then(function(cat) {
  should.not.exist(cat.owner.phoneNumber);
  return cat.populate({
    path: 'owner',
    model: 'Owner'
  });
})
.then(function(catWithOwnerPopulated) {
  ...
});

Model.batchGet(keys, options, callback)

Gets multiple items from the table.

Dog.batchGet([{ownerId: 4, name: 'Odie'}, {ownerId: 5, name: 'Lassie'}], function (err, dogs) {
  if (err) { return console.log(err); }
  console.log('Retrieved two dogs: ' + dogs);
});

Model.delete(key, [options, ]callback)

Deletes an item from the table.

Dog.delete({ownerId: 4, name: 'Odie'}, function(err) {
  if(err) { return console.log(err); }
  console.log('Bye bye Odie');
});

options parameters:

  • update (boolean): Will return the object deleted (default: false), if set to false and no object was deleted this function will fail silently.
  • returnRequest (boolean): Will resolve with the request object instead of making the request (default: false)

model.delete([options, ]callback)

Deletes the item from the table. The options parameter is optional, and should be a object type if passed in. The callback parameter is the function that will be called once the item has been deleted from the table. The error and item (if update is set to true) will be passed in as parameters to the callback function. The options object accepts the same parameters as described above in Model.delete.

odie.delete(function(err) {
  if(err) { return console.log(err); }
  console.log('Bye bye Odie');
});

model.originalItem()

This function returns the last item that was saved/received from DynamoDB. This can be useful to view the changes made since the last DynamoDB save/received that your application made for a given document. This function will return a JSON object that represents the original item.

odie.originalItem(); // {ownerId: 4, name: 'Odie'}

Model.batchDelete(keys, options, callback)

Deletes multiple items from the table.

Dog.batchDelete([
  { ownerId: 2, name: 'Princes' },
  { ownerId: 3, name: 'Toto' },
  { ownerId: 4, name: 'Odie' },
  { ownerId: 5, name: 'Lassie'}
], function (err) {
  if (err) { return console.log(err); }
  console.log('Bye bye my friends');
});

Model.update(key, update, options, callback)

Model.update(keyWithUpdate, callback)

Updates and existing item in the table. Three types of updates: $PUT, $ADD, and $DELETE.

The key can either be its own object or combined with the update object.

$PUT

Put is the default behavior. The three example below are identical.

key and updated are separate

Dog.update({ownerId: 4, name: 'Odie'}, {age: 1}, function (err) {
  if(err) { return console.log(err); }
  console.log('Just a puppy');
})

key and updated are combined

Dog.update({ownerId: 4, name: 'Odie', age: 1}, function (err) {
  if(err) { return console.log(err); }
  console.log('Just a puppy');
})
Dog.update({ownerId: 4, name: 'Odie'}, {$PUT: {age: 1}}, function (err) {
  if(err) { return console.log(err); }
  console.log('Just a puppy');
})

$ADD

Adds one or more attributes to the item. These attributes must be of the number or set type. If the attribute already exists it will be manipulated instead. If it’s a number the provided value will be added mathematically to the existing value. If the attribute is a set the provided value is appended to the set.

Dog.update({ownerId: 4, name: 'Odie'}, {$ADD: {age: 1}}, function (err) {
  if(err) { return console.log(err); }
  console.log('Birthday boy is one year older');
})

$DELETE

Removes one or more attributes from an item.

Dog.update({ownerId: 4, name: 'Odie'}, {$DELETE: {age: null}}, function (err) {
  if(err) { return console.log(err); }
  console.log('Too old to keep count');
})

Options

allowEmptyArray: boolean

If true, the attribute can be updated to an empty array. If false, empty arrays will remove the attribute. Defaults to false.

createRequired: boolean

If true, required attributes will be filled with their default values on update (regardless of you specifying them for the update). Defaults to false.

updateTimestamps: boolean

If true, the timestamps attributes will be updated. Will not do anything if timestamps attribute were not specified. Defaults to true.

updateExpires: boolean

If true, the expires attributes will be updated. Will not do anything if expires attribute were not specified. Defaults to false.

condition: string

An expression for a conditional update. See the AWS documentation for more information about condition expressions.

conditionNames: object

A map of name substitutions for the condition expression.

conditionValues: object

A map of values for the condition expression. Note that in order for automatic object conversion to work, the keys in this object must match schema attribute names.

returnValues: string

From the AWS documentation Use ReturnValues if you want to get the item attributes as they appear before or after they are updated. For UpdateItem, the valid values are:

  • NONE - If ReturnValues is not specified, or if its value is NONE, then nothing is returned. (This setting is the default for ReturnValues.)
  • ALL_OLD - Returns all of the attributes of the item, as they appeared before the UpdateItem operation.
  • UPDATED_OLD - Returns only the updated attributes, as they appeared before the UpdateItem operation.
  • ALL_NEW - Returns all of the attributes of the item, as they appear after the UpdateItem operation.
  • UPDATED_NEW - Returns only the updated attributes, as they appear after the UpdateItem operation.

Model.transaction

This object has the following methods that you can call.

  • Model.transaction.get
  • Model.transaction.create
  • Model.transaction.delete
  • Model.transaction.update
  • Model.transaction.conditionCheck

You can pass in the same parameters into each method that you do for the normal (non-transaction) methods.

These methods are only meant to only be called to instantiate the dynamoose.transaction array.

Model.transaction.conditionCheck(key, options)

This method allows you to run a conditionCheck when running a DynamoDB transaction.

Example:

Model.transaction.conditionCheck("credit1", {
  condition: "amount > :request",
  conditionNames: {
    request: "request"
  },
  conditionValues: {
    request: 100
  }
})

Options

condition: string

An expression for a conditional update. See the AWS documentation for more information about condition expressions.

conditionNames: object

A map of name substitutions for the condition expression.

conditionValues: object

A map of values for the condition expression. Note that in order for automatic object conversion to work, the keys in this object must match schema attribute names.

Model.getTableReq()

The function will return the object used to create the table with AWS. You can use this to create the table manually, for things like the Serverless deployment toolkit, or just to peak behind the scenes and see what Dynamoose is doing to create the table.

Dog.getTableReq();
//  {
//    AttributeDefinitions: attrDefs,
//    TableName: name,
//    KeySchema: keySchema,
//    ProvisionedThroughput: provThroughput
//  }

Model.plugin(pluginPackage[, pluginOptions])

WARNING: PLUGINS IS CURRENTLY IN BETA. THIS FUNCTIONALITY MIGHT CHANGE AT ANYTIME WITHOUT WARNING. DO NOT CONSIDER THIS FEATURE TO BE STABLE.

This is how you can add plugins to be run on your model. For example you can use this function like so.

var MyPlugin = require('ThePluginPackage');
var MyPluginB = require('ThePluginPackageB');
var Model = dynamoose.model('Puppy', {
    id: {
        type: Number,
        validate: function(v) {
            return v > 0;
        }
    },
    name: String,
    owner: String,
    age: {
        type: Number
    }
});
Model.plugin(MyPlugin); // this plugin will always take priority over the plugin below and be run first
Model.plugin(MyPluginB, {username: 'test', password: 'test'}); // this plugin will always take priority second and will be run after the first plugin, this plugin also passes options into the plugin

module.exports = Model;

Query

Model.query(query, options, callback)

Queries a table or index. The query parameter can either the the hash key of the table or global index or a complete query object. If the callback is provided, the exec command is called automatically, and the query parameter must be a query object.

Note: You must provide an eq for the hash key.

Dog.query('breed').eq('Beagle').exec(function (err, dogs) {
  // Look at all the beagles
});
Dog.query({breed: {eq: 'Beagle'} }, function (err, dogs) {
  // Look at all the beagles
});

Model.queryOne(query, options, callback)

Queries a table or index, sets query.limit to 1.

query.exec(callback)

Executes the query against the table or index.

query.all([delay[, max]])

Recursively query as long as lastKey exists. This function will also return a property called timesQueried indicating how many queries were completed.

delay is the time (in miliseconds) between recursive queries. Default: 1000ms (1sec)

max is the maximum number of recursive queries. Default: 0 - unlimited

query.where(rangeKey)

Set the range key of the table or index to query.

query.filter(filter)

Set the attribute on which to filter.

query.and()

Use add logic for filters.

query.or()

Use or logic for filters.

query.not()

Inverts the filter logic that follows.

query.null()

Filter attribute for null.

query.eq(value)

Hash, range key, or filter must equal the value provided. This is the only comparison option allowed for a hash key.

query.lt(value)

Range key or filter less than the value.

query.le(value)

Range key or filter less than or equal value.

query.ge(value)

Range key or filter greater than or equal value.

query.gt(value)

Range key or filter greater than the value.

query.beginsWith(value)

Range key or filter begins with value

query.between(a, b)

Range key or filter is greater than or equal a. and less than or equal to b.

query.contains(value)

Filter contains the value.

query.beginsWith(value)

Filter begins with the value.

query.in(values)

Filter is in values array.

query.limit(limit)

The maximum number of items to evaluate (not necessarily the number of matching items). If DynamoDB processes the number of items up to the limit while processing the results, it stops the operation and returns the matching values up to that point, and a key in lastKey to apply in a subsequent operation, so that you can pick up where you left off. Also, if the processed data set size exceeds 1 MB before DynamoDB reaches this limit, it stops the operation and returns the matching values up to the limit, and a key in lastKey to apply in a subsequent operation to continue the operation. For more information, see Query and Scan in the Amazon DynamoDB Developer Guide.

query.consistent()

Query with consistent read.

query.descending()

Sort in descending order.

query.ascending()

Sort in ascending order (default).

query.startAt(key)

Start query at key. Use lastKey returned in query.exec() callback.

query.attributes(attributes)

Set the list of attributes to return.

query.count()

Return the number of matching items, rather than the matching items themselves.

query.counts()

Return the counts object of matching items, rather than the matching items themselves:

{
    "count": 2,
    "scannedCount": 1000
}

If you used a filter in the request, then count is the number of items returned after the filter was applied, and scannedCount is the number of matching items before the filter was applied.

query.using(index)

You can manually specify which index to use by adding the query.using method to your query chain. The string you pass into the query.using method must match the name of an index on your table. This method is not required, by default Dynamoose will try to figure out which index to use based on your schema.

Dog.query('ownerId').using('BreedRangeIndex').eq(20).where('breed').beginsWith('Sp')

Scan

Model.scan(filter, options, callback)

Scans a table. The optional filter parameter can either be an attribute of the table or a complete filter object. If the callback is provided, the exec command is called automatically, and the scan parameter must be a Scan object.

Dog.scan('breed').contains('Terrier').exec(function (err, dogs) {
  // Look at all the Terriers
});
Dog.scan({breed: {contains: 'Terrier'} }, function (err, dogs) {
  // Look at all the Terriers
});

To get all the items in a table, do not provide a filter.

Dog.scan().exec(function (err, dogs) {
  // Look at all the dogs
  if(dogs.lastKey) { // More dogs to get
    Dog.scan().startAt(dogs.lastKey).exec(function (err, dogs) {
      // Look more dogs
    });
  }
});

To use the raw AWS filter in scanning especially for nested fields scan purposes, compose the filter object and pass it in.

  • The TableName field in raw filter is not necessary to be specified. If it is left blank, the model name will be used as default table name.
var Dog = dynamoose.model('Dog');
// this should be composed, ref: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html
var filter = {
  FilterExpression: 'details.timeWakeUp = :wakeUp',
  ExpressionAttributeValues: {
    ':wakeUp': '8am'
  }
};

Dog.scan(filter).exec()
  .then(function(dogs) {
    console.log(dogs);
  })
  .catch(function(err) {
    console.error(err);
  });

scan.exec(callback)

Executes a scan against a table

scan.all([delay[, max]])

Recursively scan as long as lastKey exists. This function will also return a property called timesScanned indicating how many scans were completed.

delay is the time (in miliseconds) between recursive scans. Default: 1000ms (1sec)

max is the maximum number of recursive scans. Default: 0 - unlimited

scan.parallel(totalSegments)

Preforms a parallel scan on the table.

totalSegments is the number of parallel scans

The results will be merged into a single array. .lastKey will be an array of lastKey objects.

Warning this can consume a lot of capacity.

scan.and()

For readability only. Scans us AND logic for multiple attributes. and() does not provide any functionality and can be omitted.

scan.where(filter) | scan.filter(filter)

Add additional attribute to the filter list.

scan.not()

Inverts the filter logic that follows.

scan.null()

Scan attribute for null.

scan.eq(value)

Attribute is equal to the value. If null, undefined, or a empty string is passed as the value, scan.null() is called.

scan.lt(value)

Attribute is less than the value.

scan.le(value)

Attribute is less than or equal value.

scan.ge(value)

Attribute is greater than or equal value.

scan.gt(value)

Attribute is greater than the value.

scan.contains(value)

Attribute contains the value.

scan.beginsWith(value)

Attribute begins with the value.

scan.in(values)

Attribute is in values array.

scan.between(a, b)

Attribute value is greater than or equal a. and less than or equal to b.

scan.limit(limit)

The maximum number of items to evaluate (not necessarily the number of matching items). If DynamoDB processes the number of items up to the limit while processing the results, it stops the operation and returns the matching values up to that point, and a key in lastKey to apply in a subsequent operation, so that you can pick up where you left off. Also, if the processed data set size exceeds 1 MB before DynamoDB reaches this limit, it stops the operation and returns the matching values up to the limit, and a key in lastKey to apply in a subsequent operation to continue the operation. For more information, see Query and Scan in the Amazon DynamoDB Developer Guide.

scan.startAt(key)

Start scan at key. Use lastKey returned in scan.exec() callback.

scan.attributes(attributes)

Set the list of attributes to return.

scan.count()

Return the number of matching items, rather than the matching items themselves.

scan.counts()

Return the counts object of matching items, rather than the matching items themselves:

{
    "count": 2,
    "scannedCount": 1000
}

If you used a filter in the scan, then count is the number of items returned after the filter was applied, and scannedCount is the number of matching items before the filter was applied.

scan.consistent()

Scan with consistent read.

Plugins (BETA)

WARNING: PLUGINS IS CURRENTLY IN BETA. THIS FUNCTIONALITY MIGHT CHANGE AT ANYTIME WITHOUT WARNING. DO NOT CONSIDER THIS FEATURE TO BE STABLE.

Please view the Model.plugin documentation for how to use plugins in your own models. This documentation will be going over how to create plugins from scratch.

Overview

All plugins will export a function. Dynamoose will pass in 2 parameters into that function. plugin and options. options is the object that was passed into Model.plugin. plugin properties are defined below.

plugin.setName

Set the name of the plugin.

Parameters accepted

  • name - Name of plugin (string)

plugin.setDescription

Set the description of the plugin.

Parameters accepted

  • description - Description of plugin (string)

plugin.on

Adds a listener to emitted events from Dynamoose. You can return a promise in the callback method that you pass in, and when it is called, Dynamoose will await for your promise to complete before continuing. Your promise must resolve and not reject. You can resolve an object with the property resolve or reject to return or reject with that result to the end user. At that point Dynamoose will take no further action. This can be useful if you want to handle more of the interaction with the user.

Parameters accepted

  • [event] - Type of event you wish to listen for from Dynamoose, you can view possible options below, if not passed in it will catch all events (string) (optional)
  • [stage] - Type of stage you wish you listen for from Dynamoose within the event, if not passed in it will catch all events (string) (optional) (note: if this is passed in event is required)
  • callback - Function to be run when event is emitted from Dynamoose (function)
    • obj - Object with properties and methods about event emitted from Dynamoose, you can view more details below (object)

Example Plugin Implementation

module.exports = function(plugin, options) {
	plugin.setName("My Plugin"); // required
	plugin.setDescription(""); // optional
	plugin.on('init', function() { // this will handle all stages related to init
		console.log("Plugin registered");
	});
	plugin.on('scan', 'preRequest', function(obj) { // this will handle only preRequest stages on the scan type
		console.log("About to make request to DynamoDB");
	});
	plugin.on('scan', 'postRequest', function(obj) { // this will handle only postRequest stages on the scan type, and will wait for promise to resolve before moving on
		return new Promise(function(resolve, reject) {
			resolve({
				resolve: "Hello World" // "Hello World" will be passed back to the promise/callback of the Dynamoose scan call
			});
		});
	});
	plugin.on('query', 'postRequest', function(obj) { // this will handle only postRequest stages on the scan type, and will wait for promise to resolve before moving on
		return new Promise(function(resolve, reject) {
			resolve({
				reject: "My Error" // "My Error" will be passed back to the promise/callback of the Dynamoose scan call as an error (not successful)
			});
		});
	});
	return plugin;
}

Items Passed Into .on callback object

Below is the default object passed into the callback object, each event might add more properties and methods to this object.

{
	model: _____, // the model instance (object)
	modelName: _____, // the model name (string)
	plugins: _____, // array of plugins registered to model (array)
	plugin: _____, // the plugin that is being called (object)
	event: {
		type: _____, // the type of event that was emitted from Dynamoose (ex. "plugin:register") (string)
		stage: _____ // the stage that was emitted from Dynamoose (ex. "pre", "post") (string)
	}
	actions: {
		registerPlugin: _____ // register function to model, just a pointer to Model.plugin function (this can be useful for creating sub-plugins) (function)
	}
}

Events emitted from Dynamoose

*

Catch all to run listener on all events emitted from Dynamoose.

plugin

Dynamoose will emit this event when your plugin is registered to a model.

Stages
  • init - Dynamoose will emit this stage when your plugin has been registered to a model
Additional Items Added to Object
{
}

plugin:register

Dynamoose will emit this event when a new plugin is registered to a model.

Stages
  • pre - Dynamoose will emit this stage when a new plugin is about to be registered to a model
  • post - Dynamoose will emit this stage when a new plugin has been registered to a model (remember: if you are listening for this stage within your plugin, this will be called after your plugin is registered, so almost instantly after it gets registered to a model)
Additional Items Added to Object
{
	event: {
		plugin: _____, // plugin package that is going to/has been registered (function)
		pluginOptions: _____ // options that were passed into plugin registration (object)
	}
}

model:scan

Dynamoose will emit this event when a scan is called on a model.

Stages
  • scan:called - Dynamoose will emit this stage when a scan is about to start
  • exec:start - Dynamoose will emit this stage when an exec is called
  • request:pre - Dynamoose will emit this stage when an scan request is about to be made to DynamoDB
  • request:post - Dynamoose will emit this stage when an scan request response has been received from DynamoDB
Additional Items Added to Object
{
	event: {
		scan: _____, // scan instance (object, Scan instance)
		callback: _____ // the function that was passed into the scan exec function (function) (only valid on `exec:start`)
		scanReq: _____ // the scan request object that will be sent to DynamoDB (object) (only valid on `request:pre`)
		data: _____ // the scan data object that was received from DynamoDB (object) (only valid on `request:post`)
		error: _____ // the scan error object that was received from DynamoDB (object) (only valid on `request:post`)

	}
	action: {
		updateCallback: _____ // function to update callback that is called (fn: function) (only valid on `exec:start`)
		updateScanReq: _____ // function to update scan request object that is sent to DynamoDB (reqObj: object) (only valid on `request:pre`)
		updateData: _____ // function to update data that was received from DynamoDB scan before proceeding (dataObj: object) (only valid on `request:post`)
		updateError: _____ // function to update error that was received from DynamoDB scan before proceeding (errorObj: object) (only valid on `request:post`)
	}
}

model:get

Dynamoose will emit this event when a get is called on a model.

Stages
  • get:called - Dynamoose will emit this stage when a get is about to start
  • request:pre - Dynamoose will emit this stage when a get request is about to be made to DynamoDB
  • request:post - Dynamoose will emit this stage when a get request response has been recieved from DynamoDB
Additional Items Added to Object
{
	event: {
		callback: _____ // the callback function for the get command (function)
		key: _____ // the key for the get request (object)
		options: _____ // the options passed into the get call (object)
		getRequest: _____ // the options passed into the get request to DynamoDB (object) (only valid on `request:pre`)
		error: _____ // the options passed into the get call (object) (only valid on `request:post`)
		data: _____ // the options passed into the get call (object) (only valid on `request:post`)

	}
	action: {
		updateCallback: _____ // function to update callback that is called (fn: function)
		updateKey: _____ // function to update key that is sent to DynamoDB (key: string)
		updateOptions: _____ // function to update options for the get call (options: object)
		updateGetRequest: _____ // function to update request options for the get call (options: object) (only valid on `request:pre`)
		updateError: _____ // function to update error received from DynamoDB (options: object) (only valid on `request:post`)
		updateData: _____ // function to update data received from DynamoDB (options: object) (only valid on `request:post`)
	}
}

model:query

Dynamoose will emit this event when a query is called on a model.

Stages
  • query:called - Dynamoose will emit this stage when a query is about to start
  • exec:start - Dynamoose will emit this stage when an exec is called
  • request:pre - Dynamoose will emit this stage when a query request is about to be made to DynamoDB
  • request:post - Dynamoose will emit this stage when a query request response has been received from DynamoDB
Additional Items Added to Object
{
	event: {
		query: _____, // query instance (object, Query instance)
		callback: _____ // the function that was passed into the query exec function (function) (only valid on `exec:start`)
		queryReq: _____ // the query request object that will be sent to DynamoDB (object) (only valid on `request:pre`)
		data: _____ // the query data object that was received from DynamoDB (object) (only valid on `request:post`)
		error: _____ // the query error object that was received from DynamoDB (object) (only valid on `request:post`)

	}
	action: {
		updateCallback: _____ // function to update callback that is called (fn: function) (only valid on `exec:start`)
		updateQueryReq: _____ // function to update query request object that is sent to DynamoDB (reqObj: object) (only valid on `request:pre`)
		updateData: _____ // function to update data that was received from DynamoDB query before proceeding (dataObj: object) (only valid on `request:post`)
		updateError: _____ // function to update error that was received from DynamoDB query before proceeding (errorObj: object) (only valid on `request:post`)
	}
}

model:put

Dynamoose will emit this event when a put is called on a model.

Stages
  • put:called - Dynamoose will emit this stage when a put is about to start
  • request:pre - Dynamoose will emit this stage when a put request is about to be made to DynamoDB
  • request:post - Dynamoose will emit this stage when a put request response has been received from DynamoDB
Additional Items Added to Object
{
	event: {
		options: _____, // options passed to put (object) (warning: in some cases this can be the callback function in the `put:called` stage)
		callback: _____, // callback passed to put (function) (warning: in some cases this can be the null if options is not passed in) (only valid on `put:called`)
		item: _____ // item that will be/has been saved to DynamoDB (function) (only valid on `request:*`)
		error: _____ // the error object that was received from DynamoDB (object) (only valid on `request:post`)
	}
	action: {
		updateCallback: _____ // function to update callback that is called (fn: function) (only valid on `put:called`)
		updateOptions: _____ // function to update options object (reqObj: object) (only valid on `put:called`)
		updateItem: _____ // function to update data that will be sent to DynamoDB (dataObj: object) (only valid on `request:pre`)
		updateError: _____ // function to update error that was received from DynamoDB query before proceeding (errorObj: object) (only valid on `request:post`)
	}
}