Repository: dynamoosejs/dynamoose
Pull request #801 (2020-04-13 03:14:26)

Changing back to behavior of dynamoose.model() without class


Patch:
diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md
index c2f687e3..22a3ade4 100644
--- a/BREAKING_CHANGES.md
+++ b/BREAKING_CHANGES.md
@@ -2,7 +2,6 @@
 
 ## 2.0 - incomplete list
 
-- Everything in Dynamoose are now classes. This includes `Model` and `Schema`. This means to initialize a new instance of one of these items, you must use the `new` keyword before it
 - `scan.count()` has been removed, and `scan.counts()` has been renamed to `scan.count()`.
 - Schema `default` value does not pass the model instance into `default` functions any more.
 - `Model.update`
@@ -10,8 +9,7 @@
 	- `$DELETE` has been renamed to `$REMOVE`
 	- `$REMOVE` (previously `$DELETE`) now maps to the correct underlying DynamoDB method instead of the previous behavior of mapping to `$REMOVE`
 	- `$PUT` has been replaced with `$SET`
-- `dynamoose.setDefaults` has been renamed to `dynamoose.Model.defaults`, and is now a property that you set, vs a method that you pass the object into
-- `dynamoose.model` has been renamed to `dynamoose.Model`
+- `dynamoose.setDefaults` has been renamed to `dynamoose.model.defaults.set`
 - `dynamoose.local` has been renamed to `dynamoose.aws.ddb.local`
 - `dynamoose.setDDB` has been renamed to `dynamoose.aws.ddb.set`
 - `dynamoose.revertDDB` has been renamed to `dynamoose.aws.ddb.revert`
diff --git a/docs/api/Document.md b/docs/api/Document.md
index 90c96e70..fabecfbf 100644
--- a/docs/api/Document.md
+++ b/docs/api/Document.md
@@ -9,7 +9,7 @@ A document/item is similar to a row in a relational database or a document in Mo
 In order to create a new document you just pass in your object into an instance of your model.
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 const myUser = new User({
 	"id": 1,
 	"name": "Tim"
diff --git a/docs/api/General.md b/docs/api/General.md
index c779e918..ff90a1f3 100644
--- a/docs/api/General.md
+++ b/docs/api/General.md
@@ -109,7 +109,7 @@ Setting an attribute value to this will cause it to bypass the `default` value,
 ```js
 const dynamoose = require("dynamoose");
 
-const User = new dynamoose.Model("User", {"id": String, "name": {"type": String, "default": "Bob"}});
+const User = dynamoose.model("User", {"id": String, "name": {"type": String, "default": "Bob"}});
 const user = new User({"id": 1, "name": dynamoose.undefined});
 await user.save();
 // {"id": 1}
diff --git a/docs/api/Model.md b/docs/api/Model.md
index 87deed27..0371fd0d 100644
--- a/docs/api/Model.md
+++ b/docs/api/Model.md
@@ -2,7 +2,7 @@
 
 The Model object represents a table in DynamoDB. It takes in both a name and a schema and has methods to retrieve, and save items in the database.
 
-## new dynamoose.Model(name, schema[, config])
+## dynamoose.model(name, schema[, config])
 
 This method is the basic entry point for creating a model in Dynamoose. When you call this method a new model is created, and it returns a Document initializer that you can use to create instances of the given model.
 
@@ -11,11 +11,11 @@ The `schema` parameter can either be an object OR a [Schema](Schema.md) instance
 ```js
 const dynamoose = require("dynamoose");
 
-const Cat = new dynamoose.Model("Cat", {"name": String});
-const Cat = new dynamoose.Model("Cat", {"name": String}, {"create": false});
+const Cat = dynamoose.model("Cat", {"name": String});
+const Cat = dynamoose.model("Cat", {"name": String}, {"create": false});
 
-const Cat = new dynamoose.Model("Cat", new dynamoose.Schema({"name": String}));
-const Cat = new dynamoose.Model("Cat", new dynamoose.Schema({"name": String}), {"create": false});
+const Cat = dynamoose.model("Cat", new dynamoose.Schema({"name": String}));
+const Cat = dynamoose.model("Cat", new dynamoose.Schema({"name": String}), {"create": false});
 ```
 
 The `config` parameter is an object used to customize settings for the model.
@@ -96,7 +96,7 @@ This function will return the object used to create the table with AWS. You can
 This function is an async function so you must wait for the promise to resolve before you are able to access the result.
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 async function printTableRequest() {
 	console.log(await User.table.create.request());
@@ -135,7 +135,7 @@ You can also pass in an object for the optional `settings` parameter that is an
 | return | What the function should return. Can be `document`, or `request`. In the event this is set to `request` the request Dynamoose will make to DynamoDB will be returned, and no request to DynamoDB will be made. If this is `request`, the function will not be async anymore. | String | `document` |
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	const myUser = await User.get(1);
@@ -156,7 +156,7 @@ User.get(1, (error, myUser) => {
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 const retrieveUserRequest = User.get(1, {"return": "request"});
 // {
@@ -174,7 +174,7 @@ User.get(1, {"return": "request"}, (error, request) => {
 In the event you have a rangeKey for your model, you can pass in an object for the `key` parameter which includes the hashKey & rangeKey.
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
+const User = dynamoose.model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
 
 try {
 	const myUser = await User.get({"id": 1, "name": "Tim"});
@@ -195,7 +195,7 @@ User.get({"id": 1, "name": "Tim"}, (error, myUser) => {
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	const myUser = await User.get({"id": 1});
@@ -234,7 +234,7 @@ You can also pass in an object for the optional `settings` parameter that is an
 | return | What the function should return. Can be `documents`, or `request`. In the event this is set to `request` the request Dynamoose will make to DynamoDB will be returned, and no request to DynamoDB will be made. If this is `request`, the function will not be async anymore. | String | `documents` |
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	const myUsers = await User.batchGet([1, 2]);
@@ -255,7 +255,7 @@ User.batchGet([1, 2], (error, myUsers) => {
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 const retrieveUsersRequest = User.batchGet([1, 2], {"return": "request"});
 // {
@@ -279,7 +279,7 @@ User.batchGet([1, 2], {"return": "request"}, (error, request) => {
 In the event you have a rangeKey for your model, you can pass in an object for the `key` parameter which includes the rangeKey & hashKey.
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
+const User = dynamoose.model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
 
 try {
 	const myUsers = await User.batchGet([{"id": 1, "name": "Tim"}, {"id": 2, "name": "Charlie"}]);
@@ -300,7 +300,7 @@ User.batchGet({"id": 1, "name": "Tim"}, (error, myUsers) => {
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	const myUsers = await User.batchGet([{"id": 1}, {"id": 2}]);
@@ -327,7 +327,7 @@ This function lets you create a new document for a given model. This function is
 If you do not pass in a `callback` parameter a promise will be returned.
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
+const User = dynamoose.model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
 
 try {
 	const user = await User.create({"id": 1, "name": "Tim"}); // If a user with `id=1` already exists in the table, an error will be thrown.
@@ -496,7 +496,7 @@ You can also pass in an object for the optional `settings` parameter that is an
 | return | What the function should return. Can be null, or `request`. In the event this is set to `request` the request Dynamoose will make to DynamoDB will be returned, and no request to DynamoDB will be made. If this is `request`, the function will not be async anymore. | String \| null | null |
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	await User.delete(1);
@@ -517,7 +517,7 @@ User.delete(1, (error) => {
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 const deleteUserRequest = User.delete(1, {"return": "request"});
 // {
@@ -535,7 +535,7 @@ User.delete(1, {"return": "request"}, (error, request) => {
 In the event you have a rangeKey for your model, you can pass in an object for the `key` parameter which includes the rangeKey & hashKey.
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
+const User = dynamoose.model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
 
 try {
 	await User.delete({"id": 1, "name": "Tim"});
@@ -556,7 +556,7 @@ User.delete({"id": 1, "name": "Tim"}, (error) => {
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	await User.delete({"id": 1});
@@ -591,7 +591,7 @@ You can also pass in an object for the optional `settings` parameter that is an
 | return | What the function should return. Can be `response`, or `request`. In the event this is set to `request` the request Dynamoose will make to DynamoDB will be returned, and no request to DynamoDB will be made. If this is `request`, the function will not be async anymore. | String | `response` |
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	const response = await User.batchDelete([1, 2]);
@@ -621,7 +621,7 @@ User.batchDelete([1, 2], (error, response) => {
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 const deleteUserRequest = User.batchDelete([1, 2], {"return": "request"});
 // {
@@ -651,7 +651,7 @@ User.batchDelete([1, 2], {"return": "request"}, (error, request) => {
 In the event you have a rangeKey for your model, you can pass in an object for the `key` parameter which includes the rangeKey & hashKey.
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
+const User = dynamoose.model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
 
 try {
 	const response = await User.batchDelete([{"id": 1, "name": "Tim"}, {"id": 2, "name": "Charlie"}]);
@@ -672,7 +672,7 @@ User.batchDelete([{"id": 1, "name": "Tim"}, {"id": 2, "name": "Charlie"}], (erro
 ```
 
 ```js
-const User = new dynamoose.Model("User", {"id": Number, "name": String});
+const User = dynamoose.model("User", {"id": Number, "name": String});
 
 try {
 	const response = await User.batchDelete([{"id": 1}, {"id": 2}]);
diff --git a/lib/Document.js b/lib/Document.js
index a488e49b..b591c9be 100644
--- a/lib/Document.js
+++ b/lib/Document.js
@@ -380,28 +380,6 @@ function DocumentCarrier(model) {
 	// TODO: figure out if there is a better way to do this below.
 	// This is needed since when creating a Model we return a Document. But we want to be able to call Model.get and other functions on the model itself. This feels like a really messy solution, but it the only way I can think of how to do it for now.
 	// Without this things like Model.get wouldn't work. You would have to do Model.Model.get instead which would be referencing the `Document.Model = model` line above.
-	Object.keys(Object.getPrototypeOf(Document.Model)).forEach((key) => {
-		if (typeof Document.Model[key] === "object" && Document.Model[key].carrier) {
-			const carrier = Document.Model[key].carrier(Document.Model);
-			Document[key] = (...args) => new carrier(...args);
-			Document[key].carrier = carrier;
-		} else if (typeof Document.Model[key] === "object") {
-			const main = (key) => {
-				utils.object.set(Document, key, {});
-				Object.keys(utils.object.get(Document.Model, key)).forEach((subKey) => {
-					const newKey = `${key}.${subKey}`;
-					if (typeof utils.object.get(Document.Model, newKey) === "object") {
-						main(newKey);
-					} else {
-						utils.object.set(Document, newKey, utils.object.get(Document.Model, newKey).bind(Document.Model));
-					}
-				});
-			};
-			main(key);
-		} else {
-			Document[key] = Document.Model[key].bind(Document.Model);
-		}
-	});
 
 	return Document;
 }
diff --git a/lib/Model/defaults.js b/lib/Model/defaults.js
new file mode 100644
index 00000000..7dac4e08
--- /dev/null
+++ b/lib/Model/defaults.js
@@ -0,0 +1,32 @@
+const original = {
+	"create": true,
+	"throughput": {
+		"read": 5,
+		"write": 5
+	},
+	"prefix": "",
+	"suffix": "",
+	"waitForActive": {
+		"enabled": true,
+		"check": {
+			"timeout": 180000,
+			"frequency": 1000
+		}
+	},
+	"update": false,
+	// "streamOptions": {
+	// 	"enabled": false,
+	// 	"type": undefined
+	// },
+	// "serverSideEncryption": false,
+	// "defaultReturnValues": "ALL_NEW",
+};
+let custom = {};
+
+module.exports = {
+	custom: {
+		"set": (val) => {custom = val;},
+		"get": () => custom
+	},
+	original
+};
\ No newline at end of file
diff --git a/lib/Model.js b/lib/Model/index.js
similarity index 95%
rename from lib/Model.js
rename to lib/Model/index.js
index caf20147..a10afb4d 100644
--- a/lib/Model.js
+++ b/lib/Model/index.js
@@ -1,19 +1,21 @@
-const Error = require("./Error");
-const Schema = require("./Schema");
-const Document = require("./Document");
-const ModelStore = require("./ModelStore");
-const utils = require("./utils");
-const aws = require("./aws");
-const Internal = require("./Internal");
+const Error = require("../Error");
+const Schema = require("../Schema");
+const Document = require("../Document");
+const ModelStore = require("../ModelStore");
+const utils = require("../utils");
+const aws = require("../aws");
+const Internal = require("../Internal");
+const DocumentRetriever = require("../DocumentRetriever");
+const defaults = require("./defaults");
 
 // Model represents one DynamoDB table
 class Model {
 	constructor(name, schema, options = {}) {
-		this.options = utils.combine_objects(options, Model.defaults, defaults);
+		this.options = utils.combine_objects(options, defaults.custom.get(), defaults.original);
 		this.name = `${this.options.prefix}${name}${this.options.suffix}`;
 
 		if (!schema) {
-			throw new Error.MissingSchemaError(`Schema hasn't been registered for model "${name}".\nUse "new dynamoose.Model(name, schema)"`);
+			throw new Error.MissingSchemaError(`Schema hasn't been registered for model "${name}".\nUse "dynamoose.model(name, schema)"`);
 		} else if (!(schema instanceof Schema)) {
 			schema = new Schema(schema);
 		}
@@ -126,7 +128,7 @@ class Model {
 
 		ModelStore(this);
 
-		return returnObject;
+		// return returnObject;
 	}
 }
 
@@ -450,7 +452,7 @@ Model.prototype.update = function (keyObj, updateObj, settings = {}, callback) {
 
 				const dynamoType = this.schema.getAttributeType(subKey, subValue, {"unknownAttributeAllowed": true});
 				const attributeExists = this.schema.attributes().includes(subKey);
-				const dynamooseUndefined = require("./index").undefined;
+				const dynamooseUndefined = require("../index").undefined;
 				if (!updateType.attributeOnly && subValue !== dynamooseUndefined) {
 					subValue = (await this.Document.objectFromSchema({[subKey]: dynamoType === "L" && !Array.isArray(subValue) ? [subValue] : subValue}, {"type": "toDynamo", "customTypesDynamo": true, "saveUnknown": true, ...updateType.objectFromSchemaSettings}))[subKey];
 				}
@@ -658,8 +660,8 @@ Model.prototype.batchDelete = function (keys, settings = {}, callback) {
 	}
 };
 
-Model.prototype.scan = {"carrier": require("./DocumentRetriever")("scan")};
-Model.prototype.query = {"carrier": require("./DocumentRetriever")("query")};
+Model.prototype.scan = {"carrier": DocumentRetriever("scan")};
+Model.prototype.query = {"carrier": DocumentRetriever("query")};
 
 // Methods
 const customMethodFunctions = (type) => {
@@ -706,30 +708,4 @@ Model.prototype.methods = {
 	"document": customMethodFunctions("document")
 };
 
-// Defaults
-const defaults = {
-	"create": true,
-	"throughput": {
-		"read": 5,
-		"write": 5
-	},
-	"prefix": "",
-	"suffix": "",
-	"waitForActive": {
-		"enabled": true,
-		"check": {
-			"timeout": 180000,
-			"frequency": 1000
-		}
-	},
-	"update": false,
-	// "streamOptions": {
-	// 	"enabled": false,
-	// 	"type": undefined
-	// },
-	// "serverSideEncryption": false,
-	// "defaultReturnValues": "ALL_NEW",
-};
-Model.defaults = defaults;
-
 module.exports = Model;
diff --git a/lib/index.js b/lib/index.js
index e940febf..791aba83 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,5 +1,43 @@
+const utils = require("./utils");
+
+const model = (...args) => {
+	const Model = require("./Model");
+	const model = new Model(...args);
+	const returnObject = model.Document;
+	Object.keys(model).forEach((key) => {
+		returnObject[key] = model[key];
+	});
+
+	Object.keys(Object.getPrototypeOf(model)).forEach((key) => {
+		if (model[key].carrier) {
+			const carrier = model[key].carrier(model);
+			returnObject[key] = (...args) => new carrier(...args);
+			returnObject[key].carrier = carrier;
+		} else if (typeof model[key] === "object") {
+			const main = (key) => {
+				utils.object.set(returnObject, key, {});
+				Object.keys(utils.object.get(model, key)).forEach((subKey) => {
+					const newKey = `${key}.${subKey}`;
+					if (typeof utils.object.get(model, newKey) === "object") {
+						main(newKey);
+					} else {
+						utils.object.set(returnObject, newKey, utils.object.get(model, newKey).bind(model));
+					}
+				});
+			};
+			main(key);
+		} else {
+			returnObject[key] = model[key].bind(model);
+		}
+	});
+	return returnObject;
+};
+model.defaults = {
+	...require("./Model/defaults").custom
+};
+
 module.exports = {
-	"Model": require("./Model"),
+	"model": model,
 	"Schema": require("./Schema"),
 	"Condition": require("./Condition"),
 	"transaction": require("./Transaction"),


Test patch:
diff --git a/test/Document.js b/test/Document.js
index e0e1199d..735bc062 100644
--- a/test/Document.js
+++ b/test/Document.js
@@ -3,7 +3,7 @@ const chai = require("chai");
 chai.use(chaiAsPromised);
 const {expect} = chai;
 const dynamoose = require("../lib");
-const {Model, Schema, aws} = dynamoose;
+const {Schema, aws} = dynamoose;
 const Document = require("../lib/Document");
 const util = require("util");
 const Error = require("../lib/Error");
@@ -16,7 +16,7 @@ describe("Document", () => {
 	});
 
 	it("Should not have internalProperties if use spread operator on object", () => {
-		const User = new Model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
+		const User = dynamoose.model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
 		const user = new User({"id": 1, "name": "Bob"});
 		expect(user[Internal.General.internalProperties]).to.exist;
 		expect({...user}[Internal.General.internalProperties]).to.not.exist;
@@ -25,7 +25,7 @@ describe("Document", () => {
 	describe("DynamoDB Conversation Methods", () => {
 		let User;
 		beforeEach(() => {
-			User = new Model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
+			User = dynamoose.model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
 		});
 		afterEach(() => {
 			User = null;
@@ -92,21 +92,21 @@ describe("Document", () => {
 	describe("document.save", () => {
 		let User, user, putParams = [], putItemFunction;
 		beforeEach(() => {
-			Model.defaults = {
+			dynamoose.model.defaults.set({
 				"create": false,
 				"waitForActive": false
-			};
+			});
 			aws.ddb.set({
 				"putItem": (params) => {
 					putParams.push(params);
 					return {"promise": putItemFunction};
 				}
 			});
-			User = new Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			user = new User({"id": 1, "name": "Charlie"});
 		});
 		afterEach(() => {
-			Model.defaults = {};
+			dynamoose.model.defaults.set({});
 			aws.ddb.revert();
 			User = null;
 			user = null;
@@ -135,7 +135,7 @@ describe("Document", () => {
 
 				it("Should save to correct table with multiple models", async () => {
 					const date = Date.now();
-					const Robot = new Model("Robot", {"id": Number, "built": Number});
+					const Robot = dynamoose.model("Robot", {"id": Number, "built": Number});
 					const robot = new Robot({"id": 2, "built": date});
 
 					putItemFunction = () => Promise.resolve();
@@ -153,7 +153,7 @@ describe("Document", () => {
 				});
 
 				it("Should not use default if dynamoose.undefined used as value for that property", async () => {
-					const Robot = new Model("Robot", {"id": Number, "age": {"type": Number, "default": 1}});
+					const Robot = dynamoose.model("Robot", {"id": Number, "age": {"type": Number, "default": 1}});
 					const robot = new Robot({"id": 2, "age": dynamoose.undefined});
 
 					putItemFunction = () => Promise.resolve();
@@ -184,7 +184,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with undefined as value without required or default as first property", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}));
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}));
 					user = new User({"name": undefined, "id": 1});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -195,7 +195,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with undefined as value without required or default as second property", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}));
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}));
 					user = new User({"id": 1, "name": undefined});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -206,7 +206,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with string set", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": [String]});
+					User = dynamoose.model("User", {"id": Number, "friends": [String]});
 					user = new User({"id": 1, "friends": ["Charlie", "Tim", "Bob"]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -217,7 +217,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with string set and saveUnknown", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new Schema({"id": Number}, {"saveUnknown": true}));
 					user = new User({"id": 1, "friends": new Set(["Charlie", "Tim", "Bob"])});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -229,7 +229,7 @@ describe("Document", () => {
 				// TODO: reenable this test
 				it.skip("Should save with correct object with string set and saveUnknown with specific values", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number}, {"saveUnknown": ["friends", "friends.1"]}));
+					User = dynamoose.model("User", new Schema({"id": Number}, {"saveUnknown": ["friends", "friends.1"]}));
 					user = new User({"id": 1, "friends": new Set(["Charlie", "Tim", "Bob"])});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -240,7 +240,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with number set", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "numbers": [Number]});
+					User = dynamoose.model("User", {"id": Number, "numbers": [Number]});
 					user = new User({"id": 1, "numbers": [5, 7]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -251,7 +251,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with number set using saveUnknown", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new Schema({"id": Number}, {"saveUnknown": true}));
 					user = new User({"id": 1, "numbers": new Set([5, 7])});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -262,7 +262,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with date set", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "times": [Date]});
+					User = dynamoose.model("User", {"id": Number, "times": [Date]});
 					const time = new Date();
 					user = new User({"id": 1, "times": [time, new Date(0)]});
 					await callType.func(user).bind(user)();
@@ -274,7 +274,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with buffer", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "data": Buffer});
+					User = dynamoose.model("User", {"id": Number, "data": Buffer});
 					user = new User({"id": 1, "data": Buffer.from("testdata")});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -285,7 +285,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with buffer set", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "data": [Buffer]});
+					User = dynamoose.model("User", {"id": Number, "data": [Buffer]});
 					user = new User({"id": 1, "data": [Buffer.from("testdata"), Buffer.from("testdata2")]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -296,7 +296,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with buffer set using saveUnknown", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new Schema({"id": Number}, {"saveUnknown": true}));
 					user = new User({"id": 1, "data": new Set([Buffer.from("testdata"), Buffer.from("testdata2")])});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -321,7 +321,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with custom type", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": String, "birthday": Date}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": String, "birthday": Date}, {"create": false, "waitForActive": false});
 					const birthday = new Date();
 					user = new User({"id": 1, "name": "Charlie", birthday});
 					await callType.func(user).bind(user)();
@@ -333,7 +333,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with custom type passed in as underlying type", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": String, "birthday": Date}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": String, "birthday": Date}, {"create": false, "waitForActive": false});
 					const birthday = new Date();
 					user = new User({"id": 1, "name": "Charlie", "birthday": birthday.getTime()});
 					await callType.func(user).bind(user)();
@@ -345,7 +345,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with custom type passed in as underlying type mixed with custom type in array", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": String, "birthday": {"type": Array, "schema": [Date]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": String, "birthday": {"type": Array, "schema": [Date]}}, {"create": false, "waitForActive": false});
 					const birthday = new Date();
 					user = new User({"id": 1, "name": "Charlie", "birthday": [birthday.getTime(), birthday]});
 					await callType.func(user).bind(user)();
@@ -357,7 +357,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with object type in schema", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"street": "hello", "country": "world"}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -368,7 +368,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with object type in schema with properties that don't exist in schema", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"street": "hello", "country": "world", "random": "test"}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -379,7 +379,7 @@ describe("Document", () => {
 
 				it("Should handle nested attributes inside object correctly for default value", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "default": "world"}}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "default": "world"}}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"street": "hello"}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -390,7 +390,7 @@ describe("Document", () => {
 
 				it("Should handle nested attributes inside object correctly for default value with object not passed in", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "default": "world"}}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "default": "world"}}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -401,7 +401,7 @@ describe("Document", () => {
 
 				it("Should throw error if required property inside object doesn't exist", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"street": "hello"}});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("address.country is a required property but has no value when trying to save document");
@@ -409,7 +409,7 @@ describe("Document", () => {
 
 				it("Should throw type mismatch error if passing in wrong type with custom type for object", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": "test"});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("Expected address to be of type object, instead found type string.");
@@ -417,7 +417,7 @@ describe("Document", () => {
 
 				it("Should throw type mismatch error if passing in wrong type for nested object attribute", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"country": true}});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("Expected address.country to be of type string, instead found type boolean.");
@@ -425,7 +425,7 @@ describe("Document", () => {
 
 				it("Should save correct object with nested objects and saveUnknown set to true", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": true}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": true}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"data": {"country": "world"}, "name": "Home"}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -436,7 +436,7 @@ describe("Document", () => {
 
 				it("Should save correct object with nested objects", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "address": {"type": Object, "schema": {"data": {"type": Object, "schema": {"country": String}}, "name": String}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"data": {"type": Object, "schema": {"country": String}}, "name": String}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"data": {"country": "world"}, "name": "Home"}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -447,7 +447,7 @@ describe("Document", () => {
 
 				it("Should save correct object with object property and saveUnknown set to true", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": true}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": true}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"country": "world", "zip": 12345}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -458,7 +458,7 @@ describe("Document", () => {
 
 				it("Should save correct object with object property and saveUnknown set to one level nested", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["address.*"]}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["address.*"]}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"country": "world", "zip": 12345, "metadata": {"name": "Home"}}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -469,7 +469,7 @@ describe("Document", () => {
 
 				it("Should save correct object with object property and saveUnknown set to all level nested", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["address.**"]}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["address.**"]}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "address": {"country": "world", "zip": 12345, "metadata": {"name": "Home"}}});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -480,7 +480,7 @@ describe("Document", () => {
 
 				it("Should save correct object with object property and saveUnknown set to one level nested with parent as array", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["addresses.*"]}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["addresses.*"]}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "addresses": [{"country": "world", "zip": 12345, "metadata": [{"name": "Home"}]}]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -491,7 +491,7 @@ describe("Document", () => {
 
 				it("Should save correct object with object property and saveUnknown set to all level nested with parent as array", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["addresses.**"]}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "address": Object}, {"saveUnknown": ["addresses.**"]}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "addresses": [{"country": "world", "zip": 12345, "metadata": [{"name": "Home"}]}]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -502,7 +502,7 @@ describe("Document", () => {
 
 				it("Should save correct object with array", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [String]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [String]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": ["Tim", "Bob"]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -513,7 +513,7 @@ describe("Document", () => {
 
 				it("Should save correct object with array as object schema", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": String}]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": String}]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": ["Tim", "Bob"]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -524,7 +524,7 @@ describe("Document", () => {
 
 				it("Should save correct object with array and objects within array", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": Number, "name": String}}]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": Number, "name": String}}]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": [{"name": "Tim", "id": 1}, {"name": "Bob", "id": 2}]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -535,7 +535,7 @@ describe("Document", () => {
 
 				it("Should save correct object with nested array's", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "data": {"type": Array, "schema": [String]}}}]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "data": {"type": Array, "schema": [String]}}}]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": [{"name": "Tim", "data": ["hello", "world"]}, {"name": "Bob", "data": ["random", "data"]}]});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -546,7 +546,7 @@ describe("Document", () => {
 
 				it("Should throw type mismatch error if passing in wrong type for nested array object", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": Number, "name": String}}]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": Number, "name": String}}]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": [true]});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("Expected friends.0 to be of type object, instead found type boolean.");
@@ -554,7 +554,7 @@ describe("Document", () => {
 
 				it("Should throw error if not passing in required property in array", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": {"type": Number, "required": true}, "name": String}}]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": {"type": Number, "required": true}, "name": String}}]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": [{"name": "Bob"}]});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("friends.0.id is a required property but has no value when trying to save document");
@@ -562,7 +562,7 @@ describe("Document", () => {
 
 				it("Should throw error if not passing in required property in array for second item", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": {"type": Number, "required": true}, "name": String}}]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": {"type": Number, "required": true}, "name": String}}]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": [{"name": "Bob", "id": 1}, {"name": "Tim"}]});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("friends.1.id is a required property but has no value when trying to save document");
@@ -570,7 +570,7 @@ describe("Document", () => {
 
 				it("Should throw error if not passing in required property in array for second item with multi nested objects", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "addresses": {"type": Array, "schema": [{"type": Object, "schema": {"country": {"type": String, "required": true}}}]}}}]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "addresses": {"type": Array, "schema": [{"type": Object, "schema": {"country": {"type": String, "required": true}}}]}}}]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "friends": [{"name": "Bob", "addresses": [{"country": "world"}]}, {"name": "Tim", "addresses": [{"country": "moon"}, {"zip": 12345}]}]});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("friends.1.addresses.1.country is a required property but has no value when trying to save document");
@@ -578,7 +578,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with expires set to a number", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": 10000});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": 10000});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams[0].TableName).to.eql("User");
@@ -591,7 +591,7 @@ describe("Document", () => {
 
 				it("Should store whole number for expires", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": 10000});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": 10000});
 					user = new User({"id": 1, "name": "Charlie", "ttl": new Date(1002)});
 					await callType.func(user).bind(user)();
 					expect(parseFloat(putParams[0].Item.ttl.N) % 1).to.eql(0);
@@ -599,7 +599,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with expires set to object", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": {"attribute": "expires", "ttl": 10000}});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": {"attribute": "expires", "ttl": 10000}});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams[0].TableName).to.eql("User");
@@ -612,7 +612,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with expires set to object with no attribute", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": {"ttl": 10000}});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}), {"create": false, "waitForActive": false, "expires": {"ttl": 10000}});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams[0].TableName).to.eql("User");
@@ -625,7 +625,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with timestamps set to true", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}, {"timestamps": true}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}, {"timestamps": true}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams[0].TableName).to.eql("User");
@@ -654,7 +654,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with custom timestamps attribute names", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}, {"timestamps": {"createdAt": "created", "updatedAt": "updated"}}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}, {"timestamps": {"createdAt": "created", "updatedAt": "updated"}}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams[0].TableName).to.eql("User");
@@ -683,7 +683,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with timestamps but no createdAt timestamp", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}, {"timestamps": {"createdAt": null, "updatedAt": "updatedAt"}}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}, {"timestamps": {"createdAt": null, "updatedAt": "updatedAt"}}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams[0].TableName).to.eql("User");
@@ -709,7 +709,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with timestamps but no updatedAt timestamp", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number, "name": String}, {"timestamps": {"createdAt": "createdAt", "updatedAt": false}}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number, "name": String}, {"timestamps": {"createdAt": "createdAt", "updatedAt": false}}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams[0].TableName).to.eql("User");
@@ -736,7 +736,7 @@ describe("Document", () => {
 
 				it("Should throw type mismatch error if passing in wrong type with custom type", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": String, "birthday": Date}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": String, "birthday": Date}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Charlie", "birthday": "test"});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("Expected birthday to be of type date, instead found type string.");
@@ -754,7 +754,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with undefined attributes in schema", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": Number}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": Number}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -765,7 +765,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with default values", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "default": 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "default": 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -776,7 +776,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with default value as function", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "default": () => 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "default": () => 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -787,7 +787,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with default value as async function", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "default": async () => 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "default": async () => 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -798,7 +798,7 @@ describe("Document", () => {
 
 				it("Should throw type mismatch error if passing in wrong type for default value", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "default": () => true}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "default": () => true}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("Expected age to be of type number, instead found type boolean.");
@@ -807,7 +807,7 @@ describe("Document", () => {
 				it("Should save with correct object with default value as custom type", async () => {
 					putItemFunction = () => Promise.resolve();
 					const date = new Date();
-					User = new Model("User", {"id": Number, "timestamp": {"type": Date, "default": () => date}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "timestamp": {"type": Date, "default": () => date}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -818,7 +818,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with validation value", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "validate": 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "validate": 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "age": 5});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -829,7 +829,7 @@ describe("Document", () => {
 
 				it("Should throw error if invalid value for validation value", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "validate": 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "validate": 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "age": 4});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("age with a value of 4 had a validation error when trying to save the document");
@@ -839,7 +839,7 @@ describe("Document", () => {
 				it("Should not run validation function if property doesn't exist", async () => {
 					putItemFunction = () => Promise.resolve();
 					let didRun = false;
-					User = new Model("User", {"id": Number, "age": {"type": Number, "validate": () => {didRun = true; return true;}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "validate": () => {didRun = true; return true;}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 					await callType.func(user).bind(user)();
 					expect(didRun).to.be.false;
@@ -848,7 +848,7 @@ describe("Document", () => {
 				it("Should run validation function if property is falsy", async () => {
 					putItemFunction = () => Promise.resolve();
 					let didRun = false;
-					User = new Model("User", {"id": Number, "data": {"type": Boolean, "validate": () => {didRun = true; return true;}}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "data": {"type": Boolean, "validate": () => {didRun = true; return true;}}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "data": false});
 					await callType.func(user).bind(user)();
 					expect(didRun).to.be.true;
@@ -856,7 +856,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with validation function", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "validate": (val) => val > 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "validate": (val) => val > 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "age": 6});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -867,7 +867,7 @@ describe("Document", () => {
 
 				it("Should throw error if invalid value for validation function", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "validate": (val) => val > 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "validate": (val) => val > 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "age": 4});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("age with a value of 4 had a validation error when trying to save the document");
@@ -875,7 +875,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with validation async function", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "validate": async (val) => val > 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "validate": async (val) => val > 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "age": 6});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -886,7 +886,7 @@ describe("Document", () => {
 
 				it("Should throw error if invalid value for validation async function", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "age": {"type": Number, "validate": async (val) => val > 5}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "validate": async (val) => val > 5}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "age": 4});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("age with a value of 4 had a validation error when trying to save the document");
@@ -894,7 +894,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with validation RegExp", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "validate": /.../gu}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "validate": /.../gu}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Tom"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -905,7 +905,7 @@ describe("Document", () => {
 
 				it("Should throw error if invalid value for validation RegExp", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "validate": /.../gu}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "validate": /.../gu}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "a"});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("name with a value of a had a validation error when trying to save the document");
@@ -913,7 +913,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with required property", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "required": true}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "required": true}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Tom"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -924,7 +924,7 @@ describe("Document", () => {
 
 				it("Should throw error if required property not passed in", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "required": true}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "required": true}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("name is a required property but has no value when trying to save document");
@@ -932,7 +932,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with enum property", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "enum": ["Tim", "Tom"]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "enum": ["Tim", "Tom"]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Tom"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -943,7 +943,7 @@ describe("Document", () => {
 
 				it("Should throw error if value does not match value in enum property", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "enum": ["Tim", "Tom"]}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "enum": ["Tim", "Tom"]}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Bob"});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("name must equal [\"Tim\",\"Tom\"], but is set to Bob");
@@ -951,7 +951,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with forceDefault property", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "default": "Tim", "forceDefault": true}}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": "Tim", "forceDefault": true}}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Tom"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -962,7 +962,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with saveUnknown set to true", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number}, {"saveUnknown": true}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number}, {"saveUnknown": true}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Tom"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -973,7 +973,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with saveUnknown set to an array with correct attribute", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number}, {"saveUnknown": ["name"]}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number}, {"saveUnknown": ["name"]}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Tom"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -984,7 +984,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with saveUnknown set to false", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", new Schema({"id": Number}, {"saveUnknown": false}), {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", new Schema({"id": Number}, {"saveUnknown": false}), {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Tom"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -995,7 +995,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with set function for attribute", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -1006,7 +1006,7 @@ describe("Document", () => {
 
 				it("Should save with correct object with async set function for attribute", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": {"type": String, "set": async (val) => `${val}-set`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "set": async (val) => `${val}-set`}});
 					user = new User({"id": 1, "name": "Charlie"});
 					await callType.func(user).bind(user)();
 					expect(putParams).to.eql([{
@@ -1017,7 +1017,7 @@ describe("Document", () => {
 
 				it("Should work correctly if attributes added to document after initalization", async () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
 					user = new User();
 					user.id = 1;
 					user.name = "Charlie";
@@ -1030,7 +1030,7 @@ describe("Document", () => {
 
 				it("Should throw error if object contains properties that have type mismatch with schema", () => {
 					putItemFunction = () => Promise.resolve();
-					User = new Model("User", {"id": Number, "name": String, "age": Number}, {"create": false, "waitForActive": false});
+					User = dynamoose.model("User", {"id": Number, "name": String, "age": Number}, {"create": false, "waitForActive": false});
 					user = new User({"id": 1, "name": "Charlie", "age": "test"});
 
 					return expect(callType.func(user).bind(user)()).to.be.rejectedWith("Expected age to be of type number, instead found type string.");
@@ -1066,7 +1066,7 @@ describe("Document", () => {
 							return {"promise": putItemFunction};
 						}
 					});
-					const model = new Model("User2", {"id": Number, "name": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0, "timeout": 100}}});
+					const model = dynamoose.model("User2", {"id": Number, "name": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0, "timeout": 100}}});
 					const document = new model({"id": 1, "name": "Charlie"});
 					await utils.set_immediate_promise();
 
@@ -1099,7 +1099,7 @@ describe("Document", () => {
 	describe("document.original", () => {
 		let model;
 		beforeEach(() => {
-			model = new Model("User", {"id": Number}, {"create": false, "waitForActive": false});
+			model = dynamoose.model("User", {"id": Number}, {"create": false, "waitForActive": false});
 		});
 		afterEach(() => {
 			model = null;
@@ -1128,21 +1128,21 @@ describe("Document", () => {
 	describe("document.delete", () => {
 		let User, user, deleteParams, deleteItemFunction;
 		beforeEach(() => {
-			Model.defaults = {
+			dynamoose.model.defaults.set({
 				"create": false,
 				"waitForActive": false
-			};
+			});
 			aws.ddb.set({
 				"deleteItem": (params) => {
 					deleteParams = params;
 					return {"promise": deleteItemFunction};
 				}
 			});
-			User = new Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			user = new User({"id": 1, "name": "Charlie"});
 		});
 		afterEach(() => {
-			Model.defaults = {};
+			dynamoose.model.defaults.set({});
 			aws.ddb.revert();
 			User = null;
 			user = null;
@@ -1179,13 +1179,13 @@ describe("Document", () => {
 
 	describe("conformToSchema", () => {
 		beforeEach(() => {
-			Model.defaults = {
+			dynamoose.model.defaults.set({
 				"create": false,
 				"waitForActive": false
-			};
+			});
 		});
 		afterEach(() => {
-			Model.defaults = {};
+			dynamoose.model.defaults.set({});
 		});
 
 		const tests = [
@@ -1197,14 +1197,14 @@ describe("Document", () => {
 		tests.forEach((test) => {
 			if (test.error) {
 				it(`Should throw error ${test.error} correctly for input ${JSON.stringify(test.input)} and schema ${JSON.stringify(test.schema)}`, () => {
-					const User = new Model("User", test.schema);
+					const User = dynamoose.model("User", test.schema);
 					const user = new User(test.input);
 
 					return expect(user.conformToSchema()).to.be.rejectedWith("Expected age to be of type number, instead found type string.");
 				});
 			} else {
 				it(`Should modify ${JSON.stringify(test.input)} correctly for schema ${JSON.stringify(test.schema)}`, async () => {
-					const User = new Model("User", test.schema);
+					const User = dynamoose.model("User", test.schema);
 					const user = new User(test.input);
 
 					const obj = await user.conformToSchema();
@@ -1219,7 +1219,7 @@ describe("Document", () => {
 	describe("Document.isDynamoObject", () => {
 		let User;
 		beforeEach(() => {
-			User = new Model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
+			User = dynamoose.model("User", {"id": Number, "name": String}, {"create": false, "waitForActive": false});
 		});
 		afterEach(() => {
 			User = null;
@@ -1325,7 +1325,7 @@ describe("Document", () => {
 
 	describe("Document.attributesWithSchema", () => {
 		it("Should be a function", () => {
-			expect(new Model("User", {"id": Number}, {"create": false, "waitForActive": false}).attributesWithSchema).to.be.a("function");
+			expect(dynamoose.model("User", {"id": Number}, {"create": false, "waitForActive": false}).attributesWithSchema).to.be.a("function");
 		});
 
 		const tests = [
@@ -1363,14 +1363,14 @@ describe("Document", () => {
 
 		tests.forEach((test) => {
 			it(`Should return ${JSON.stringify(test.output)} for input of ${JSON.stringify(test.input)} with a schema of ${JSON.stringify(test.schema)}`, () => {
-				expect((new Model("User", test.schema, {"create": false, "waitForActive": false})).attributesWithSchema(test.input).sort()).to.eql(test.output.sort());
+				expect((dynamoose.model("User", test.schema, {"create": false, "waitForActive": false})).attributesWithSchema(test.input).sort()).to.eql(test.output.sort());
 			});
 		});
 	});
 
 	describe("Document.objectFromSchema", () => {
 		it("Should be a function", () => {
-			expect(new Model("User", {"id": Number}, {"create": false, "waitForActive": false}).objectFromSchema).to.be.a("function");
+			expect(dynamoose.model("User", {"id": Number}, {"create": false, "waitForActive": false}).objectFromSchema).to.be.a("function");
 		});
 
 		const tests = [
@@ -1730,9 +1730,9 @@ describe("Document", () => {
 		tests.forEach((test) => {
 			let model;
 			if (test.model) {
-				model = new Model(...test.model);
+				model = dynamoose.model(...test.model);
 			} else {
-				model = new Model("User", test.schema, {"create": false, "waitForActive": false});
+				model = dynamoose.model("User", test.schema, {"create": false, "waitForActive": false});
 			}
 
 			if (test.error) {
diff --git a/test/Model.js b/test/Model.js
index cb455bc3..675db45d 100644
--- a/test/Model.js
+++ b/test/Model.js
@@ -10,53 +10,45 @@ const util = require("util");
 
 describe("Model", () => {
 	beforeEach(() => {
-		dynamoose.Model.defaults = {"create": false, "waitForActive": false};
+		dynamoose.model.defaults.set({"create": false, "waitForActive": false});
 	});
 	afterEach(() => {
-		dynamoose.Model.defaults = {};
+		dynamoose.model.defaults.set({});
 	});
 
 	it("Should have a model proprety on the dynamoose object", () => {
-		expect(dynamoose.Model).to.exist;
-	});
-
-	it("Should resolve to correct file for dynamoose object", () => {
-		expect(dynamoose.Model).to.eql(require("../lib/Model"));
+		expect(dynamoose.model).to.exist;
 	});
 
 	it("Should be a function", () => {
-		expect(dynamoose.Model).to.be.a("function");
+		expect(dynamoose.model).to.be.a("function");
 	});
 
 	describe("Initialization", () => {
-		it("Should throw an error if not using `new` keyword", () => {
-			expect(() => dynamoose.Model()).to.throw("Class constructor Model cannot be invoked without 'new'");
-		});
-
 		it("Should throw an error if no schema is passed in", () => {
-			expect(() => new dynamoose.Model("Cat")).to.throw(Error.MissingSchemaError);
+			expect(() => dynamoose.model("Cat")).to.throw(Error.MissingSchemaError);
 		});
 
 		it("Should throw same error as no schema if nothing passed in", () => {
-			expect(() => new dynamoose.Model()).to.throw(Error.MissingSchemaError);
+			expect(() => dynamoose.model()).to.throw(Error.MissingSchemaError);
 		});
 
 		it("Should create a schema if not passing in schema instance", () => {
 			const schema = {"name": String};
-			const Cat = new dynamoose.Model("Cat", schema);
+			const Cat = dynamoose.model("Cat", schema);
 			expect(Cat.Model.schema).to.not.eql(schema);
 			expect(Cat.Model.schema).to.be.an.instanceof(dynamoose.Schema);
 		});
 
 		it("Should use schema instance if passed in", () => {
 			const schema = new dynamoose.Schema({"name": String});
-			const Cat = new dynamoose.Model("Cat", schema);
+			const Cat = dynamoose.model("Cat", schema);
 			expect(Cat.Model.schema).to.eql(schema);
 			expect(Cat.Model.schema).to.be.an.instanceof(dynamoose.Schema);
 		});
 
 		it("Should not fail with initialization if table doesn't exist", async () => {
-			dynamoose.Model.defaults = {};
+			dynamoose.model.defaults.set({});
 			const itemsCalled = [];
 			dynamoose.aws.ddb.set({
 				"createTable": () => {
@@ -82,7 +74,7 @@ describe("Model", () => {
 				failed = true;
 			};
 			process.on("unhandledRejection", errorHandler);
-			new dynamoose.Model(tableName, {"id": String});
+			dynamoose.model(tableName, {"id": String});
 			await utils.timeout(100);
 			expect(failed).to.be.false;
 			process.removeListener("unhandledRejection", errorHandler);
@@ -95,10 +87,10 @@ describe("Model", () => {
 		];
 		const optionsC = [
 			{"name": "Defaults", "func": (type, value, ...args) => {
-				dynamoose.Model.defaults = {...dynamoose.Model.defaults, [type]: value};
-				return new dynamoose.Model(...args);
+				dynamoose.model.defaults.set({...dynamoose.model.defaults.get(), [type]: value});
+				return dynamoose.model(...args);
 			}},
-			{"name": "Options", "func": (type, value, ...args) => new dynamoose.Model(...args, {[type]: value})}
+			{"name": "Options", "func": (type, value, ...args) => dynamoose.model(...args, {[type]: value})}
 		];
 		optionsB.forEach((optionB) => {
 			describe(optionB.name, () => {
@@ -118,11 +110,11 @@ describe("Model", () => {
 
 		describe("Model.ready", () => {
 			it("Should not be ready to start", () => {
-				expect(new dynamoose.Model("Cat", {"id": String}, {"create": false}).Model.ready).to.be.false;
+				expect(dynamoose.model("Cat", {"id": String}, {"create": false}).Model.ready).to.be.false;
 			});
 
 			it("Should set ready after setup flow", async () => {
-				const model = new dynamoose.Model("Cat", {"id": String}, {"create": false});
+				const model = dynamoose.model("Cat", {"id": String}, {"create": false});
 				await utils.set_immediate_promise();
 				expect(model.Model.ready).to.be.true;
 			});
@@ -136,7 +128,7 @@ describe("Model", () => {
 						"promise": () => Promise.resolve(describeTableResponse)
 					})
 				});
-				const model = new dynamoose.Model("Cat", {"id": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0}}});
+				const model = dynamoose.model("Cat", {"id": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0}}});
 				await utils.set_immediate_promise();
 
 				let pendingTaskPromiseResolved = false;
@@ -155,7 +147,7 @@ describe("Model", () => {
 			});
 
 			it("Should immediately resolve pendingTaskPromises promise if table is already ready", async () => {
-				const model = new dynamoose.Model("Cat", {"id": String}, {"create": false});
+				const model = dynamoose.model("Cat", {"id": String}, {"create": false});
 				await utils.set_immediate_promise();
 
 				let pendingTaskPromiseResolved = false;
@@ -170,9 +162,9 @@ describe("Model", () => {
 		describe("Creation", () => {
 			let createTableParams = null;
 			beforeEach(() => {
-				dynamoose.Model.defaults = {
+				dynamoose.model.defaults.set({
 					"waitForActive": false
-				};
+				});
 			});
 			beforeEach(() => {
 				createTableParams = null;
@@ -193,7 +185,7 @@ describe("Model", () => {
 
 			it("Should call createTable with correct parameters", async () => {
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String});
+				dynamoose.model(tableName, {"id": String});
 				await utils.set_immediate_promise();
 				expect(createTableParams).to.eql({
 					"AttributeDefinitions": [
@@ -218,7 +210,7 @@ describe("Model", () => {
 
 			it("Should call createTable with correct parameters with capacity as number", async () => {
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String}, {"throughput": 1});
+				dynamoose.model(tableName, {"id": String}, {"throughput": 1});
 				await utils.set_immediate_promise();
 				expect(createTableParams).to.eql({
 					"AttributeDefinitions": [
@@ -243,7 +235,7 @@ describe("Model", () => {
 
 			it("Should call createTable with correct parameters with capacity as object", async () => {
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String}, {"throughput": {"read": 2, "write": 3}});
+				dynamoose.model(tableName, {"id": String}, {"throughput": {"read": 2, "write": 3}});
 				await utils.set_immediate_promise();
 				expect(createTableParams).to.eql({
 					"AttributeDefinitions": [
@@ -268,7 +260,7 @@ describe("Model", () => {
 
 			it("Should call createTable with correct parameters with capacity as ON_DEMAND", async () => {
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String}, {"throughput": "ON_DEMAND"});
+				dynamoose.model(tableName, {"id": String}, {"throughput": "ON_DEMAND"});
 				await utils.set_immediate_promise();
 				expect(createTableParams).to.eql({
 					"AttributeDefinitions": [
@@ -300,13 +292,13 @@ describe("Model", () => {
 				});
 
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String});
+				dynamoose.model(tableName, {"id": String});
 				await utils.set_immediate_promise();
 				expect(createTableParams).to.eql(null);
 			});
 
 			it("Should not call createTable if create option set to false", async () => {
-				new dynamoose.Model("Cat", {"id": String}, {"create": false});
+				dynamoose.model("Cat", {"id": String}, {"create": false});
 				await utils.set_immediate_promise();
 				expect(createTableParams).to.eql(null);
 			});
@@ -326,7 +318,7 @@ describe("Model", () => {
 					"describeTable": () => ({"promise": () => Promise.resolve()})
 				});
 
-				new dynamoose.Model("Cat", {"id": String});
+				dynamoose.model("Cat", {"id": String});
 				await utils.set_immediate_promise();
 				expect(self).to.be.an("object");
 				expect(Object.keys(self)).to.eql(["promise"]);
@@ -337,7 +329,7 @@ describe("Model", () => {
 		describe("Wait For Active", () => {
 			let describeTableParams = [], describeTableFunction;
 			beforeEach(() => {
-				dynamoose.Model.defaults = {
+				dynamoose.model.defaults.set({
 					"create": false,
 					"waitForActive": {
 						"enabled": true,
@@ -346,7 +338,7 @@ describe("Model", () => {
 							"frequency": 1
 						}
 					}
-				};
+				});
 			});
 			beforeEach(() => {
 				describeTableParams = [];
@@ -372,7 +364,7 @@ describe("Model", () => {
 						"TableStatus": "ACTIVE"
 					}
 				});
-				new dynamoose.Model(tableName, {"id": String});
+				dynamoose.model(tableName, {"id": String});
 				await utils.set_immediate_promise();
 				expect(describeTableParams).to.eql([{
 					"TableName": tableName
@@ -386,7 +378,7 @@ describe("Model", () => {
 						"TableStatus": describeTableParams.length > 1 ? "ACTIVE" : "CREATING"
 					}
 				});
-				new dynamoose.Model(tableName, {"id": String});
+				dynamoose.model(tableName, {"id": String});
 				await utils.timeout(5);
 				expect(describeTableParams).to.eql([{
 					"TableName": tableName
@@ -402,7 +394,7 @@ describe("Model", () => {
 						"TableStatus": "CREATING"
 					}
 				});
-				new dynamoose.Model(tableName, {"id": String});
+				dynamoose.model(tableName, {"id": String});
 				const errorHandler = utils.empty_function;
 				process.on("unhandledRejection", errorHandler);
 				await utils.timeout(15);
@@ -415,7 +407,7 @@ describe("Model", () => {
 				describeTableFunction = () => Promise.reject({"error": "ERROR"});
 
 				let error;
-				new dynamoose.Model(tableName, {"id": String});
+				dynamoose.model(tableName, {"id": String});
 				const errorHandler = (err) => error = err;
 				process.on("unhandledRejection", errorHandler);
 				await utils.timeout(15);
@@ -429,7 +421,7 @@ describe("Model", () => {
 					return Promise.resolve({"Table": {"TableStatus": "ACTIVE"}});
 				};
 
-				new dynamoose.Model(tableName, {"id": String}, {"create": true});
+				dynamoose.model(tableName, {"id": String}, {"create": true});
 				await utils.timeout(5);
 				expect(describeTableParams).to.eql([{
 					"TableName": tableName
@@ -440,10 +432,10 @@ describe("Model", () => {
 		describe("Update", () => {
 			let describeTableFunction, updateTableParams = [];
 			beforeEach(() => {
-				dynamoose.Model.defaults = {
+				dynamoose.model.defaults.set({
 					"create": false,
 					"update": true
-				};
+				});
 			});
 			beforeEach(() => {
 				updateTableParams = [];
@@ -478,7 +470,7 @@ describe("Model", () => {
 						"TableStatus": "ACTIVE"
 					}
 				});
-				new dynamoose.Model(tableName, {"id": String}, {"throughput": {"read": 1, "write": 2}});
+				dynamoose.model(tableName, {"id": String}, {"throughput": {"read": 1, "write": 2}});
 				await utils.set_immediate_promise();
 				expect(updateTableParams).to.eql([]);
 			});
@@ -494,7 +486,7 @@ describe("Model", () => {
 						"TableStatus": "ACTIVE"
 					}
 				});
-				new dynamoose.Model(tableName, {"id": String}, {"throughput": {"read": 1, "write": 2}});
+				dynamoose.model(tableName, {"id": String}, {"throughput": {"read": 1, "write": 2}});
 				await utils.set_immediate_promise();
 				expect(updateTableParams).to.eql([{
 					"ProvisionedThroughput": {
@@ -516,7 +508,7 @@ describe("Model", () => {
 						"TableStatus": "ACTIVE"
 					}
 				});
-				new dynamoose.Model(tableName, {"id": String}, {"throughput": "ON_DEMAND"});
+				dynamoose.model(tableName, {"id": String}, {"throughput": "ON_DEMAND"});
 				await utils.set_immediate_promise();
 				expect(updateTableParams).to.eql([{
 					"BillingMode": "PAY_PER_REQUEST",
@@ -532,7 +524,7 @@ describe("Model", () => {
 						"TableStatus": "ACTIVE"
 					}
 				});
-				new dynamoose.Model(tableName, {"id": String}, {"throughput": 5});
+				dynamoose.model(tableName, {"id": String}, {"throughput": 5});
 				await utils.set_immediate_promise();
 				expect(updateTableParams).to.eql([{
 					"ProvisionedThroughput": {
@@ -547,10 +539,10 @@ describe("Model", () => {
 		describe("Time To Live", () => {
 			let updateTTLParams = [], describeTTL, describeTTLFunction;
 			beforeEach(() => {
-				dynamoose.Model.defaults = {
+				dynamoose.model.defaults.set({
 					"create": false,
 					"update": true
-				};
+				});
 			});
 			beforeEach(() => {
 				updateTTLParams = [];
@@ -591,7 +583,7 @@ describe("Model", () => {
 			it("Should call updateTimeToLive with correct parameters if TTL is disabled", async () => {
 				describeTTL = {"TimeToLiveDescription": {"TimeToLiveStatus": "DISABLED"}};
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String}, {"expires": 1000});
+				dynamoose.model(tableName, {"id": String}, {"expires": 1000});
 				await utils.set_immediate_promise();
 				expect(updateTTLParams).to.eql([{
 					"TableName": tableName,
@@ -605,7 +597,7 @@ describe("Model", () => {
 			it("Should not call updateTimeToLive with correct parameters if TTL is enabled", async () => {
 				describeTTL = {"TimeToLiveDescription": {"TimeToLiveStatus": "ENABLED"}};
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String}, {"expires": 1000});
+				dynamoose.model(tableName, {"id": String}, {"expires": 1000});
 				await utils.set_immediate_promise();
 				expect(updateTTLParams).to.eql([]);
 			});
@@ -613,7 +605,7 @@ describe("Model", () => {
 			it("Should not call updateTimeToLive with correct parameters if TTL is enabling", async () => {
 				describeTTL = {"TimeToLiveDescription": {"TimeToLiveStatus": "ENABLING"}};
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String}, {"expires": 1000});
+				dynamoose.model(tableName, {"id": String}, {"expires": 1000});
 				await utils.set_immediate_promise();
 				expect(updateTTLParams).to.eql([]);
 			});
@@ -630,7 +622,7 @@ describe("Model", () => {
 					};
 				};
 				const tableName = "Cat";
-				const model = new dynamoose.Model(tableName, {"id": String}, {"expires": {"ttl": 1000, "attribute": "expires"}});
+				const model = dynamoose.model(tableName, {"id": String}, {"expires": {"ttl": 1000, "attribute": "expires"}});
 				await model.Model.pendingTaskPromise();
 				expect(updateTTLParams).to.eql([{
 					"TableName": tableName,
@@ -646,7 +638,7 @@ describe("Model", () => {
 			it("Should call updateTimeToLive with correct parameters for custom attribute if TTL is disabled", async () => {
 				describeTTL = {"TimeToLiveDescription": {"TimeToLiveStatus": "DISABLED"}};
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String}, {"expires": {"ttl": 1000, "attribute": "expires"}});
+				dynamoose.model(tableName, {"id": String}, {"expires": {"ttl": 1000, "attribute": "expires"}});
 				await utils.set_immediate_promise();
 				expect(updateTTLParams).to.eql([{
 					"TableName": tableName,
@@ -659,7 +651,7 @@ describe("Model", () => {
 
 			it("Should not call updateTimeToLive if no expires", async () => {
 				const tableName = "Cat";
-				new dynamoose.Model(tableName, {"id": String});
+				dynamoose.model(tableName, {"id": String});
 				await utils.set_immediate_promise();
 				expect(updateTTLParams).to.eql([]);
 			});
@@ -669,7 +661,7 @@ describe("Model", () => {
 	describe("Model.get", () => {
 		let User, getItemParams, getItemFunction;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			getItemParams = null;
 			getItemFunction = null;
 			dynamoose.aws.ddb.set({
@@ -727,7 +719,7 @@ describe("Model", () => {
 
 				it("Should send correct params to getItem if we pass in an object with range key", async () => {
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "name": {"S": "Charlie"}}});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
 					await callType.func(User).bind(User)({"id": 1, "name": "Charlie"});
 					expect(getItemParams).to.be.an("object");
 					expect(getItemParams).to.eql({
@@ -782,14 +774,14 @@ describe("Model", () => {
 				});
 
 				it("Should return undefined for expired object", async () => {
-					User = new dynamoose.Model("User", {"id": Number}, {"expires": {"ttl": 1000, "items": {"returnExpired": false}}});
+					User = dynamoose.model("User", {"id": Number}, {"expires": {"ttl": 1000, "items": {"returnExpired": false}}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "ttl": {"N": "1"}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.eql(undefined);
 				});
 
 				it("Should return expired object if returnExpired is not set", async () => {
-					User = new dynamoose.Model("User", {"id": Number}, {"expires": 1000});
+					User = dynamoose.model("User", {"id": Number}, {"expires": 1000});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "ttl": {"N": "1"}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -799,7 +791,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values with saveUnknown", async () => {
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "hello": {"S": "world"}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -809,7 +801,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for string set", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "friends": [String]});
+					User = dynamoose.model("User", {"id": Number, "friends": [String]});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "friends": {"SS": ["Charlie", "Bob"]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -819,7 +811,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for string set with saveUnknown", async () => {
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "friends": {"SS": ["Charlie", "Bob"]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -829,7 +821,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for number set", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "numbers": [Number]});
+					User = dynamoose.model("User", {"id": Number, "numbers": [Number]});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "numbers": {"NS": ["5", "7"]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -839,7 +831,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for number set with saveUnknown", async () => {
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "numbers": {"NS": ["5", "7"]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -849,7 +841,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for date set", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "times": [Date]});
+					User = dynamoose.model("User", {"id": Number, "times": [Date]});
 					const time = new Date();
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "times": {"NS": [time.getTime(), 0]}}});
 					const user = await callType.func(User).bind(User)(1);
@@ -860,7 +852,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for buffer", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "data": Buffer});
+					User = dynamoose.model("User", {"id": Number, "data": Buffer});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "data": {"B": Buffer.from("testdata")}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -870,7 +862,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for buffer set", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "data": [Buffer]});
+					User = dynamoose.model("User", {"id": Number, "data": [Buffer]});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "data": {"BS": [Buffer.from("testdata"), Buffer.from("testdata2")]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -880,7 +872,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values for buffer set with saveUnknown", async () => {
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "data": {"BS": [Buffer.from("testdata"), Buffer.from("testdata2")]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -890,7 +882,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values if using custom types", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "birthday": Date});
+					User = dynamoose.model("User", {"id": Number, "name": String, "birthday": Date});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "name": {"S": "Charlie"}, "birthday": {"N": "1"}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -901,7 +893,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values if using custom types but value doesn't exist", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "birthday": Date});
+					User = dynamoose.model("User", {"id": Number, "name": String, "birthday": Date});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "name": {"S": "Charlie"}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -912,14 +904,14 @@ describe("Model", () => {
 				});
 
 				it("Should throw type mismatch error if passing in wrong type with custom type", () => {
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "birthday": Date});
+					User = dynamoose.model("User", {"id": Number, "name": String, "birthday": Date});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "name": {"S": "Charlie"}, "birthday": {"S": "Hello World"}}});
 
 					return expect(callType.func(User).bind(User)(1)).to.be.rejectedWith("Expected birthday to be of type date, instead found type string.");
 				});
 
 				it("Should return object with correct values with object property", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "address": {"M": {"street": {"S": "hello"}, "country": {"S": "world"}}}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -929,7 +921,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values with object property with elements that don't exist in schema", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "address": {"M": {"zip": {"N": "12345"}, "country": {"S": "world"}}}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -939,21 +931,21 @@ describe("Model", () => {
 				});
 
 				it("Should throw type mismatch error if passing in wrong type with custom type for object", () => {
-					User = new dynamoose.Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "address": {"S": "test"}}});
 
 					return expect(callType.func(User).bind(User)(1)).to.be.rejectedWith("Expected address to be of type object, instead found type string.");
 				});
 
 				it("Should throw type mismatch error if passing in wrong type for nested object attribute", () => {
-					User = new dynamoose.Model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"street": String, "country": {"type": String, "required": true}}}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "address": {"M": {"country": {"BOOL": true}}}}});
 
 					return expect(callType.func(User).bind(User)(1)).to.be.rejectedWith("Expected address.country to be of type string, instead found type boolean.");
 				});
 
 				it("Should return object with correct values with object property and saveUnknown set to true", async () => {
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number, "address": Object}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number, "address": Object}, {"saveUnknown": true}));
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "address": {"M": {"zip": {"N": "12345"}, "country": {"S": "world"}}}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -963,7 +955,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values with multiple nested object properties and saveUnknown set to true", async () => {
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number, "address": Object}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number, "address": Object}, {"saveUnknown": true}));
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "address": {"M": {"data": {"M": {"country": {"S": "world"}}}, "name": {"S": "Home"}}}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -973,7 +965,7 @@ describe("Model", () => {
 				});
 
 				it("Should return object with correct values with multiple nested object properties", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "address": {"type": Object, "schema": {"data": {"type": Object, "schema": {"country": String}}, "name": String}}});
+					User = dynamoose.model("User", {"id": Number, "address": {"type": Object, "schema": {"data": {"type": Object, "schema": {"country": String}}, "name": String}}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "address": {"M": {"data": {"M": {"country": {"S": "world"}}}, "name": {"S": "Home"}}}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -983,7 +975,7 @@ describe("Model", () => {
 				});
 
 				it("Should return correct object for array properties", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "friends": {"type": Array, "schema": [String]}});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [String]}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "friends": {"L": [{"S": "Tim"}, {"S": "Bob"}]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -993,7 +985,7 @@ describe("Model", () => {
 				});
 
 				it("Should return correct object with array and objects within array", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": Number, "name": String}}]}});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"id": Number, "name": String}}]}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "friends": {"L": [{"M": {"name": {"S": "Tim"}, "id": {"N": "1"}}}, {"M": {"name": {"S": "Bob"}, "id": {"N": "2"}}}]}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -1003,7 +995,7 @@ describe("Model", () => {
 				});
 
 				it("Should return correct object if attribute has a get function", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "get": (val) => `${val}-get`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "get": (val) => `${val}-get`}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "name": {"S": "Charlie"}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -1013,7 +1005,7 @@ describe("Model", () => {
 				});
 
 				it("Should return correct object if attribute has an async get function", async () => {
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "get": async (val) => `${val}-get`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "get": async (val) => `${val}-get`}});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "name": {"S": "Charlie"}}});
 					const user = await callType.func(User).bind(User)(1);
 					expect(user).to.be.an("object");
@@ -1044,7 +1036,7 @@ describe("Model", () => {
 				});
 
 				it("Should throw error if Dynamo object contains properties that have type mismatch with schema", () => {
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "age": Number});
+					User = dynamoose.model("User", {"id": Number, "name": String, "age": Number});
 					getItemFunction = () => Promise.resolve({"Item": {"id": {"N": "1"}, "name": {"S": "Charlie"}, "age": {"S": "Hello World"}}});
 
 					return expect(callType.func(User).bind(User)(1)).to.be.rejectedWith("Expected age to be of type number, instead found type string.");
@@ -1064,7 +1056,7 @@ describe("Model", () => {
 							"promise": getItemFunction
 						})
 					});
-					const model = new dynamoose.Model("User", {"id": Number, "name": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0, "timeout": 100}}});
+					const model = dynamoose.model("User", {"id": Number, "name": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0, "timeout": 100}}});
 					await utils.set_immediate_promise();
 
 					let user;
@@ -1090,7 +1082,7 @@ describe("Model", () => {
 	describe("Model.batchGet", () => {
 		let User, params, promiseFunction;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			params = null;
 			promiseFunction = null;
 			dynamoose.aws.ddb.set({
@@ -1279,7 +1271,7 @@ describe("Model", () => {
 							"promise": promiseFunction
 						})
 					});
-					const model = new dynamoose.Model("User", {"id": Number, "name": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0, "timeout": 100}}});
+					const model = dynamoose.model("User", {"id": Number, "name": String}, {"waitForActive": {"enabled": true, "check": {"frequency": 0, "timeout": 100}}});
 					await utils.set_immediate_promise();
 
 					let users;
@@ -1305,7 +1297,7 @@ describe("Model", () => {
 	describe("Model.create", () => {
 		let User, createItemParams, createItemFunction;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			dynamoose.aws.ddb.set({
 				"putItem": (params) => {
 					createItemParams = params;
@@ -1417,7 +1409,7 @@ describe("Model", () => {
 
 				it("Should send correct params to putItem with set function", async () => {
 					createItemFunction = () => Promise.resolve();
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
 					await callType.func(User).bind(User)({"id": 1, "name": "Charlie"});
 					expect(createItemParams).to.be.an("object");
 					expect(createItemParams).to.eql({
@@ -1439,7 +1431,7 @@ describe("Model", () => {
 
 				it("Should send correct params to putItem with async set function", async () => {
 					createItemFunction = () => Promise.resolve();
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "set": async (val) => `${val}-set`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "set": async (val) => `${val}-set`}});
 					await callType.func(User).bind(User)({"id": 1, "name": "Charlie"});
 					expect(createItemParams).to.be.an("object");
 					expect(createItemParams).to.eql({
@@ -1465,7 +1457,7 @@ describe("Model", () => {
 	describe("Model.batchPut", () => {
 		let User, params, promiseFunction;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			dynamoose.aws.ddb.set({
 				"batchWriteItem": (paramsB) => {
 					params = paramsB;
@@ -1569,7 +1561,7 @@ describe("Model", () => {
 	describe("Model.update", () => {
 		let User, updateItemParams, updateItemFunction;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String, "age": Number});
+			User = dynamoose.model("User", {"id": Number, "name": String, "age": Number});
 			dynamoose.aws.ddb.set({
 				"updateItem": (params) => {
 					updateItemParams = params;
@@ -1618,7 +1610,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem for trying to update unknown properties with saveUnknown", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number, "name": String, "age": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number, "name": String, "age": Number}, {"saveUnknown": true}));
 					await callType.func(User).bind(User)({"id": 1, "name": "Charlie", "random": "hello world"});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -1671,7 +1663,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem for trying to update unknown list properties with saveUnknown", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number, "name": String, "age": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number, "name": String, "age": Number}, {"saveUnknown": true}));
 					await callType.func(User).bind(User)({"id": 1, "name": "Charlie", "random": ["hello world"]});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -1700,7 +1692,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem for trying to update unknown list properties with saveUnknown as $ADD", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number, "name": String, "age": Number}, {"saveUnknown": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number, "name": String, "age": Number}, {"saveUnknown": true}));
 					await callType.func(User).bind(User)({"id": 1}, {"$SET": {"name": "Charlie"}, "$ADD": {"random": ["hello world"]}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -1857,7 +1849,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem when using undefined to restore to default property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
 					await callType.func(User).bind(User)({"id": 1, "name": undefined});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -1882,7 +1874,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem when using undefined to delete default property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "age": Number});
+					User = dynamoose.model("User", {"id": Number, "name": String, "age": Number});
 					await callType.func(User).bind(User)({"id": 1, "name": undefined});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -1903,7 +1895,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem when using dynamoose.undefined to delete default property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
 					await callType.func(User).bind(User)({"id": 1, "name": dynamoose.undefined});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -1924,7 +1916,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem when using dynamoose.undefined to delete default property using $REMOVE", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
 					await callType.func(User).bind(User)({"id": 1}, {"$REMOVE": {"name": dynamoose.undefined}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -1945,7 +1937,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem when using dynamoose.undefined to delete default property using $SET", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": () => "Charlie"}, "age": Number});
 					await callType.func(User).bind(User)({"id": 1}, {"$SET": {"name": dynamoose.undefined}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2018,7 +2010,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem with $SET update expression for list", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "friends": {"type": Array, "schema": [String]}});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [String]}});
 					await callType.func(User).bind(User)({"id": 1}, {"friends": ["Bob"]});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2125,7 +2117,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem with $ADD with one item for list append", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
+					User = dynamoose.model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
 					await callType.func(User).bind(User)({"id": 1}, {"$ADD": {"friends": "Tim"}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2150,7 +2142,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem with $ADD with multiple items for list append", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
+					User = dynamoose.model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
 					await callType.func(User).bind(User)({"id": 1}, {"$ADD": {"friends": ["Tim", "Charlie"]}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2216,7 +2208,7 @@ describe("Model", () => {
 				it("Should send correct params to updateItem with $SET date", async () => {
 					updateItemFunction = () => Promise.resolve({});
 					const date = new Date();
-					User = new dynamoose.Model("User", {"id": Number, "birthday": Date});
+					User = dynamoose.model("User", {"id": Number, "birthday": Date});
 					await callType.func(User).bind(User)({"id": 1}, {"birthday": date});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2241,7 +2233,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem with $SET date as number", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "birthday": Date});
+					User = dynamoose.model("User", {"id": Number, "birthday": Date});
 					await callType.func(User).bind(User)({"id": 1}, {"birthday": 0});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2266,7 +2258,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem with $ADD date as number", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "birthday": Date});
+					User = dynamoose.model("User", {"id": Number, "birthday": Date});
 					await callType.func(User).bind(User)({"id": 1}, {"$ADD": {"birthday": 1000}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2291,7 +2283,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem for timestamps with updateAt", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number, "name": String}, {"timestamps": true}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number, "name": String}, {"timestamps": true}));
 					const date = Date.now();
 					await callType.func(User).bind(User)({"id": 1}, {"name": "Charlie"});
 					expect(updateItemParams).to.be.an("object");
@@ -2322,7 +2314,7 @@ describe("Model", () => {
 
 				it("Should send correct params to updateItem with conditional", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", new dynamoose.Schema({"id": Number, "name": String, "active": Boolean}));
+					User = dynamoose.model("User", new dynamoose.Schema({"id": Number, "name": String, "active": Boolean}));
 					const condition = new dynamoose.Condition("active").eq(true);
 					await callType.func(User).bind(User)({"id": 1}, {"name": "Charlie"}, {condition});
 					expect(updateItemParams).to.be.an("object");
@@ -2363,35 +2355,35 @@ describe("Model", () => {
 
 				it("Should not throw error if validation passes", () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "myNumber": {"type": Number, "validate": (val) => val > 10}});
+					User = dynamoose.model("User", {"id": Number, "myNumber": {"type": Number, "validate": (val) => val > 10}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"myNumber": 11})).to.not.be.rejected;
 				});
 
 				it("Should not throw error if validation doesn't pass when using $ADD", () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "myNumber": {"type": Number, "validate": (val) => val > 10}});
+					User = dynamoose.model("User", {"id": Number, "myNumber": {"type": Number, "validate": (val) => val > 10}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"$ADD": {"myNumber": 5}})).to.not.be.rejected;
 				});
 
 				it("Should throw error if validation doesn't pass", () => {
 					updateItemFunction = () => Promise.reject({"error": "ERROR"});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "validate": (val) => val.length > 10}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "validate": (val) => val.length > 10}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"name": "Bob"})).to.be.rejectedWith("name with a value of Bob had a validation error when trying to save the document");
 				});
 
 				it("Should throw error if value not in enum", () => {
 					updateItemFunction = () => Promise.reject({"error": "ERROR"});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "enum": ["Bob", "Tim"]}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "enum": ["Bob", "Tim"]}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"name": "Todd"})).to.be.rejectedWith("name must equal [\"Bob\",\"Tim\"], but is set to Todd");
 				});
 
 				it("Should not throw error if value is in enum", () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "enum": ["Bob", "Tim"]}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "enum": ["Bob", "Tim"]}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"name": "Bob"})).to.not.be.rejected;
 				});
@@ -2404,63 +2396,63 @@ describe("Model", () => {
 
 				it("Should throw error for type mismatch for add", () => {
 					updateItemFunction = () => Promise.reject({"error": "ERROR"});
-					User = new dynamoose.Model("User", {"id": Number, "myNumber": Number});
+					User = dynamoose.model("User", {"id": Number, "myNumber": Number});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"$ADD": {"myNumber": false}})).to.be.rejectedWith("Expected myNumber to be of type number, instead found type boolean.");
 				});
 
 				it("Should throw error for one item list append type mismatch", () => {
 					updateItemFunction = () => Promise.reject({"error": "ERROR"});
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
+					User = dynamoose.model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"$ADD": {"friends": false}})).to.be.rejectedWith("Expected friends.0 to be of type string, instead found type boolean.");
 				});
 
 				it("Should throw error for multiple item list append type mismatch", () => {
 					updateItemFunction = () => Promise.reject({"error": "ERROR"});
-					User = new dynamoose.Model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
+					User = dynamoose.model("User", {"id": Number, "name": String, "friends": {"type": Array, "schema": [String]}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"$ADD": {"friends": [1, 5]}})).to.be.rejectedWith("Expected friends.0 to be of type string, instead found type number.");
 				});
 
 				it("Should throw error if trying to remove required property", () => {
 					updateItemFunction = () => Promise.reject({"error": "ERROR"});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "required": true}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "required": true}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"$REMOVE": ["name"]})).to.be.rejectedWith("name is a required property but has no value when trying to save document");
 				});
 
 				it("Should not throw error if trying to modify required property", () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "required": true}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "required": true}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"name": "Bob"})).to.not.be.rejected;
 				});
 
 				it("Should not throw error if not modifying required property", () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "required": true}, "friends": [String]});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "required": true}, "friends": [String]});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"friends": ["Bob"]})).to.not.be.rejected;
 				});
 
 				it("Should throw error if trying to replace object without nested required property", () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "data": {"type": Object, "schema": {"name": String, "age": {"type": Number, "required": true}}}});
+					User = dynamoose.model("User", {"id": Number, "data": {"type": Object, "schema": {"name": String, "age": {"type": Number, "required": true}}}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"data": {"name": "Charlie"}})).to.be.rejectedWith("data.age is a required property but has no value when trying to save document");
 				});
 
 				it("Should throw error if trying to replace object with $SET without nested required property", () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "data": {"type": Object, "schema": {"name": String, "age": {"type": Number, "required": true}}}});
+					User = dynamoose.model("User", {"id": Number, "data": {"type": Object, "schema": {"name": String, "age": {"type": Number, "required": true}}}});
 
 					return expect(callType.func(User).bind(User)({"id": 1}, {"$SET": {"data": {"name": "Charlie"}}})).to.be.rejectedWith("data.age is a required property but has no value when trying to save document");
 				});
 
 				it("Should use default value if deleting property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": "Bob"}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": "Bob"}});
 					await callType.func(User).bind(User)({"id": 1}, {"$REMOVE": ["name"]});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2485,7 +2477,7 @@ describe("Model", () => {
 
 				it("Shouldn't use default value if modifying property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": "Bob"}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": "Bob"}});
 					await callType.func(User).bind(User)({"id": 1}, {"name": "Tim"});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2510,7 +2502,7 @@ describe("Model", () => {
 
 				it("Shouldn't use default value if modifying different property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": "Bob"}, "data": String});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": "Bob"}, "data": String});
 					await callType.func(User).bind(User)({"id": 1}, {"data": "test"});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2535,7 +2527,7 @@ describe("Model", () => {
 
 				it("Should use forceDefault value if deleting property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": "Bob", "forceDefault": true}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": "Bob", "forceDefault": true}});
 					await callType.func(User).bind(User)({"id": 1}, {"$REMOVE": ["name"]});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2560,7 +2552,7 @@ describe("Model", () => {
 
 				it("Should use forceDefault value if modifying property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": "Bob", "forceDefault": true}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": "Bob", "forceDefault": true}});
 					await callType.func(User).bind(User)({"id": 1}, {"name": "Tim"});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2585,7 +2577,7 @@ describe("Model", () => {
 
 				it("Should use forceDefault value if adding to property that is a string set", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "friends": {"type": [String], "default": ["Bob"], "forceDefault": true}});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": [String], "default": ["Bob"], "forceDefault": true}});
 					await callType.func(User).bind(User)({"id": 1}, {"$ADD": {"friends": ["Tim"]}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2610,7 +2602,7 @@ describe("Model", () => {
 
 				it("Should use forceDefault value if adding to property that is a string list", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "friends": {"type": Array, "schema": [String], "default": ["Bob"], "forceDefault": true}});
+					User = dynamoose.model("User", {"id": Number, "friends": {"type": Array, "schema": [String], "default": ["Bob"], "forceDefault": true}});
 					await callType.func(User).bind(User)({"id": 1}, {"$ADD": {"friends": ["Tim"]}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2637,7 +2629,7 @@ describe("Model", () => {
 
 				it("Should use forceDefault value if modifying different property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "default": "Bob", "forceDefault": true}, "data": String});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "default": "Bob", "forceDefault": true}, "data": String});
 					await callType.func(User).bind(User)({"id": 1}, {"data": "test"});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2666,7 +2658,7 @@ describe("Model", () => {
 
 				it("Shouldn't conform to enum if property isn't being updated", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "enum": ["Bob", "Tim"]}, "data": String});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "enum": ["Bob", "Tim"]}, "data": String});
 					await callType.func(User).bind(User)({"id": 1}, {"data": "test"});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2691,7 +2683,7 @@ describe("Model", () => {
 
 				it("Should call set modifier if setting property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
 					await callType.func(User).bind(User)({"id": 1}, {"name": "Bob"});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2716,7 +2708,7 @@ describe("Model", () => {
 
 				it("Should call set modifier if setting property using $SET", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "set": (val) => `${val}-set`}});
 					await callType.func(User).bind(User)({"id": 1}, {"$SET": {"name": "Bob"}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2741,7 +2733,7 @@ describe("Model", () => {
 
 				it("Should not call set modifier if adding to property", async () => {
 					updateItemFunction = () => Promise.resolve({});
-					User = new dynamoose.Model("User", {"id": Number, "age": {"type": Number, "set": (val) => val * 10}});
+					User = dynamoose.model("User", {"id": Number, "age": {"type": Number, "set": (val) => val * 10}});
 					await callType.func(User).bind(User)({"id": 1}, {"$ADD": {"age": 5}});
 					expect(updateItemParams).to.be.an("object");
 					expect(updateItemParams).to.eql({
@@ -2776,7 +2768,7 @@ describe("Model", () => {
 	describe("Model.delete", () => {
 		let User, deleteItemParams, deleteItemFunction;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			dynamoose.aws.ddb.set({
 				"deleteItem": (params) => {
 					deleteItemParams = params;
@@ -2831,7 +2823,7 @@ describe("Model", () => {
 
 				it("Should send correct params to deleteItem if we pass in an object with range key", async () => {
 					deleteItemFunction = () => Promise.resolve();
-					User = new dynamoose.Model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
+					User = dynamoose.model("User", {"id": Number, "name": {"type": String, "rangeKey": true}});
 					await callType.func(User).bind(User)({"id": 1, "name": "Charlie"});
 					expect(deleteItemParams).to.be.an("object");
 					expect(deleteItemParams).to.eql({
@@ -2883,7 +2875,7 @@ describe("Model", () => {
 	describe("Model.batchDelete", () => {
 		let User, params, promiseFunction;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			dynamoose.aws.ddb.set({
 				"batchWriteItem": (paramsB) => {
 					params = paramsB;
@@ -2986,11 +2978,11 @@ describe("Model", () => {
 
 	describe("Model.table.create.request", () => {
 		it("Should be a function", () => {
-			expect(new dynamoose.Model("User", {"id": String}).table.create.request).to.be.a("function");
+			expect(dynamoose.model("User", {"id": String}).table.create.request).to.be.a("function");
 		});
 
 		it("Should return correct result", async () => {
-			expect(await new dynamoose.Model("User", {"id": String}).table.create.request()).to.eql({
+			expect(await dynamoose.model("User", {"id": String}).table.create.request()).to.eql({
 				"TableName": "User",
 				"ProvisionedThroughput": {
 					"ReadCapacityUnits": 5,
@@ -3015,7 +3007,7 @@ describe("Model", () => {
 	describe("Model.transaction", () => {
 		let User;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 		});
 		afterEach(() => {
 			User = null;
@@ -3217,7 +3209,7 @@ describe("Model", () => {
 	describe("Model.methods", () => {
 		let User, user;
 		beforeEach(() => {
-			User = new dynamoose.Model("User", {"id": Number, "name": String});
+			User = dynamoose.model("User", {"id": Number, "name": String});
 			user = new User();
 		});
 		afterEach(() => {
@@ -3383,16 +3375,16 @@ describe("Model", () => {
 
 describe("model", () => {
 	beforeEach(() => {
-		dynamoose.Model.defaults = {"create": false, "waitForActive": false};
+		dynamoose.model.defaults.set({"create": false, "waitForActive": false});
 	});
 	afterEach(() => {
-		dynamoose.Model.defaults = {};
+		dynamoose.model.defaults.set({});
 	});
 
 	let Cat;
 	beforeEach(() => {
 		const schema = new dynamoose.Schema({"name": String});
-		Cat = new dynamoose.Model("Cat", schema);
+		Cat = dynamoose.model("Cat", schema);
 	});
 
 	it("Should allow creating instance of Model", () => {
diff --git a/test/Query.js b/test/Query.js
index 5ca67543..efadbbc1 100644
--- a/test/Query.js
+++ b/test/Query.js
@@ -7,10 +7,10 @@ const util = require("util");
 
 describe("Query", () => {
 	beforeEach(() => {
-		dynamoose.Model.defaults = {"create": false, "waitForActive": false};
+		dynamoose.model.defaults.set({"create": false, "waitForActive": false});
 	});
 	afterEach(() => {
-		dynamoose.Model.defaults = {};
+		dynamoose.model.defaults.set({});
 	});
 
 	let queryPromiseResolver, queryParams;
@@ -30,7 +30,7 @@ describe("Query", () => {
 
 	let Model;
 	beforeEach(() => {
-		Model = new dynamoose.Model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}});
+		Model = dynamoose.model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}});
 	});
 
 	describe("Model.query", () => {
@@ -85,13 +85,13 @@ describe("Query", () => {
 
 				it("Should return undefined for expired object", async () => {
 					queryPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}, "ttl": {"N": "1"}}]});
-					Model = new dynamoose.Model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}}, {"expires": {"ttl": 1000, "items": {"returnExpired": false}}});
+					Model = dynamoose.model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}}, {"expires": {"ttl": 1000, "items": {"returnExpired": false}}});
 					expect((await callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).map((item) => ({...item}))).to.eql([]);
 				});
 
 				it("Should return expired object if returnExpired is not set", async () => {
 					queryPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}, "ttl": {"N": "1"}}]});
-					Model = new dynamoose.Model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}}, {"expires": {"ttl": 1000}});
+					Model = dynamoose.model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}}, {"expires": {"ttl": 1000}});
 					expect((await callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie", "ttl": new Date(1000)}]);
 				});
 
@@ -101,13 +101,13 @@ describe("Query", () => {
 				});
 
 				it("Should return correct result if using custom types", async () => {
-					Model = new dynamoose.Model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}, "birthday": Date});
+					Model = dynamoose.model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}, "birthday": Date});
 					queryPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}, "birthday": {"N": "1"}}]});
 					expect((await callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie", "birthday": new Date(1)}]);
 				});
 
 				it("Should return correct result for saveUnknown", async () => {
-					Model = new dynamoose.Model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "index": {"global": true}}}, {"saveUnknown": true}));
+					Model = dynamoose.model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "index": {"global": true}}}, {"saveUnknown": true}));
 					queryPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}, "age": {"N": 10}}]});
 					expect((await callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie", "age": 10}]);
 				});
@@ -145,7 +145,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec if querying main key", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": String, "age": Number});
+					Model = dynamoose.model("Cat", {"id": String, "name": String, "age": Number});
 					await callType.func(Model.query("id").eq("HelloWorld").exec).bind(Model.query("id").eq("HelloWorld"))();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -161,7 +161,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec if querying main key with range key", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": {"type": String, "rangeKey": true}, "age": Number});
+					Model = dynamoose.model("Cat", {"id": String, "name": {"type": String, "rangeKey": true}, "age": Number});
 					await callType.func(Model.query("id").eq("HelloWorld").where("name").eq("Charlie").exec).bind(Model.query("id").eq("HelloWorld").where("name").eq("Charlie"))();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -179,7 +179,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec if querying main key with range key as less than comparison", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": String, "age": {"type": Number, "rangeKey": true}});
+					Model = dynamoose.model("Cat", {"id": String, "name": String, "age": {"type": Number, "rangeKey": true}});
 					await callType.func(Model.query("id").eq("HelloWorld").where("age").lt(10).exec).bind(Model.query("id").eq("HelloWorld").where("age").lt(10))();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -197,7 +197,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec using range key as less than comparison", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
+					Model = dynamoose.model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
 					await callType.func(Model.query("name").eq("Charlie").where("age").lt(10).exec).bind(Model.query("name").eq("Charlie").where("age").lt(10))();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -216,7 +216,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec using range key as between comparison", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
+					Model = dynamoose.model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
 					await callType.func(Model.query("name").eq("Charlie").where("age").between(10, 20).exec).bind(Model.query("name").eq("Charlie").where("age").between(10, 20))();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -236,7 +236,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec using range key as exists comparison", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
+					Model = dynamoose.model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
 					await callType.func(Model.query("name").eq("Charlie").where("age").exists().exec).bind(Model.query("name").eq("Charlie").where("age").exists())();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -255,7 +255,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec using range key as contains comparison", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
+					Model = dynamoose.model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
 					await callType.func(Model.query("name").eq("Charlie").where("age").contains(10).exec).bind(Model.query("name").eq("Charlie").where("age").contains(10))();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -275,7 +275,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec using range key as beginsWith comparison", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
+					Model = dynamoose.model("Cat", {"id": String, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
 					await callType.func(Model.query("name").eq("Charlie").where("age").beginsWith(10).exec).bind(Model.query("name").eq("Charlie").where("age").beginsWith(10))();
 					expect(queryParams).to.eql({
 						"TableName": "Cat",
@@ -328,7 +328,7 @@ describe("Query", () => {
 				});
 
 				it("Should send correct request on query.exec for one object passed in and multiple indexes but only one equals", async () => {
-					Model = new dynamoose.Model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true}}, "name": {"type": String, "index": {"global": true}}});
+					Model = dynamoose.model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true}}, "name": {"type": String, "index": {"global": true}}});
 					queryPromiseResolver = () => ({"Items": []});
 					await callType.func(Model.query({"age": {"le": 5}, "name": {"eq": "Charlie"}}).exec).bind(Model.query({"age": {"le": 5}, "name": {"eq": "Charlie"}}))();
 					expect(queryParams).to.eql({
@@ -348,7 +348,7 @@ describe("Query", () => {
 				});
 
 				it("Should send correct request on query.exec for one object passed in and multiple indexes and multiple equals", async () => {
-					Model = new dynamoose.Model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true}}, "name": {"type": String, "index": {"global": true}}});
+					Model = dynamoose.model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true}}, "name": {"type": String, "index": {"global": true}}});
 					queryPromiseResolver = () => ({"Items": []});
 					await callType.func(Model.query({"age": {"eq": 5}, "name": {"eq": "Charlie"}}).exec).bind(Model.query({"age": {"eq": 5}, "name": {"eq": "Charlie"}}))();
 					expect(queryParams).to.eql({
@@ -389,7 +389,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec with multiple filters", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}, "age": Number, "breed": String});
+					Model = dynamoose.model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true}}, "age": Number, "breed": String});
 					const query = Model.query("name").eq("Charlie").filter("breed").eq("Cat").and().filter("age").gt(2);
 					await callType.func(query.exec).bind(query)();
 					expect(queryParams).to.eql({
@@ -440,7 +440,7 @@ describe("Query", () => {
 
 				it("Should send correct request on query.exec with query condition", async () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
+					Model = dynamoose.model("Cat", {"id": Number, "name": {"type": String, "index": {"global": true, "rangeKey": "age"}}, "age": Number});
 					const query = Model.query("name").eq("Charlie").where("age").eq(10);
 					await callType.func(query.exec).bind(query)();
 					expect(queryParams).to.eql({
@@ -459,7 +459,7 @@ describe("Query", () => {
 				});
 
 				it("Should send correct request on query.exec for index with hash and range key but only querying hash key", async () => {
-					Model = new dynamoose.Model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true, "rangeKey": "name"}}, "name": String});
+					Model = dynamoose.model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true, "rangeKey": "name"}}, "name": String});
 					queryPromiseResolver = () => ({"Items": []});
 					await callType.func(Model.query("age").eq(1).exec).bind(Model.query("age").eq(1))();
 					expect(queryParams).to.eql({
@@ -476,26 +476,26 @@ describe("Query", () => {
 				});
 
 				it("Should return correct result with get function for attribute", async () => {
-					Model = new dynamoose.Model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "index": {"global": true}, "get": (val) => `${val}-get`}}));
+					Model = dynamoose.model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "index": {"global": true}, "get": (val) => `${val}-get`}}));
 					queryPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}}]});
 					expect((await callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie-get"}]);
 				});
 
 				it("Should return correct result with async get function for attribute", async () => {
-					Model = new dynamoose.Model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "index": {"global": true}, "get": async (val) => `${val}-get`}}));
+					Model = dynamoose.model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "index": {"global": true}, "get": async (val) => `${val}-get`}}));
 					queryPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}}]});
 					expect((await callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie-get"}]);
 				});
 
 				it("Should throw error if no indexes exist on model", () => {
 					queryPromiseResolver = () => ({"Items": []});
-					Model = new dynamoose.Model("Cat", new dynamoose.Schema({"id": Number, "name": String}));
+					Model = dynamoose.model("Cat", new dynamoose.Schema({"id": Number, "name": String}));
 
 					return expect(callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).to.be.rejectedWith("Index can't be found for query.");
 				});
 
 				it("Should throw error if not querying index hash key", async () => {
-					Model = new dynamoose.Model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true, "rangeKey": "name"}}, "name": String});
+					Model = dynamoose.model("Cat", {"id": Number, "age": {"type": Number, "index": {"global": true, "rangeKey": "name"}}, "name": String});
 					queryPromiseResolver = () => ({"Items": []});
 					return expect(callType.func(Model.query("name").eq("Charlie").exec).bind(Model.query("name").eq("Charlie"))()).to.be.rejectedWith("Index can't be found for query.");
 				});
diff --git a/test/Scan.js b/test/Scan.js
index 4295336b..1e17ec22 100644
--- a/test/Scan.js
+++ b/test/Scan.js
@@ -7,10 +7,10 @@ const util = require("util");
 
 describe("Scan", () => {
 	beforeEach(() => {
-		dynamoose.Model.defaults = {"create": false, "waitForActive": false};
+		dynamoose.model.defaults.set({"create": false, "waitForActive": false});
 	});
 	afterEach(() => {
-		dynamoose.Model.defaults = {};
+		dynamoose.model.defaults.set({});
 	});
 
 	let scanPromiseResolver, scanParams;
@@ -30,7 +30,7 @@ describe("Scan", () => {
 
 	let Model;
 	beforeEach(() => {
-		Model = new dynamoose.Model("Cat", {"id": Number, "name": String});
+		Model = dynamoose.model("Cat", {"id": Number, "name": String});
 	});
 
 	describe("Model.scan", () => {
@@ -85,13 +85,13 @@ describe("Scan", () => {
 
 				it("Should return undefined for expired object", async () => {
 					scanPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "ttl": {"N": "1"}}]});
-					Model = new dynamoose.Model("Cat", {"id": Number}, {"expires": {"ttl": 1000, "items": {"returnExpired": false}}});
+					Model = dynamoose.model("Cat", {"id": Number}, {"expires": {"ttl": 1000, "items": {"returnExpired": false}}});
 					expect((await callType.func(Model.scan().exec).bind(Model.scan())()).map((item) => ({...item}))).to.eql([]);
 				});
 
 				it("Should return expired object if returnExpired is not set", async () => {
 					scanPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "ttl": {"N": "1"}}]});
-					Model = new dynamoose.Model("Cat", {"id": Number}, {"expires": {"ttl": 1000}});
+					Model = dynamoose.model("Cat", {"id": Number}, {"expires": {"ttl": 1000}});
 					expect((await callType.func(Model.scan().exec).bind(Model.scan())()).map((item) => ({...item}))).to.eql([{"id": 1, "ttl": new Date(1000)}]);
 				});
 
@@ -101,13 +101,13 @@ describe("Scan", () => {
 				});
 
 				it("Should return correct result if using custom types", async () => {
-					Model = new dynamoose.Model("Cat", {"id": Number, "name": String, "birthday": Date});
+					Model = dynamoose.model("Cat", {"id": Number, "name": String, "birthday": Date});
 					scanPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}, "birthday": {"N": "1"}}]});
 					expect((await callType.func(Model.scan().exec).bind(Model.scan())()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie", "birthday": new Date(1)}]);
 				});
 
 				it("Should return correct result for saveUnknown", async () => {
-					Model = new dynamoose.Model("Cat", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
+					Model = dynamoose.model("Cat", new dynamoose.Schema({"id": Number}, {"saveUnknown": true}));
 					scanPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}}]});
 					expect((await callType.func(Model.scan().exec).bind(Model.scan())()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie"}]);
 				});
@@ -206,13 +206,13 @@ describe("Scan", () => {
 				});
 
 				it("Should return correct result for get function on attribute", async () => {
-					Model = new dynamoose.Model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "get": (val) => `${val}-get`}}));
+					Model = dynamoose.model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "get": (val) => `${val}-get`}}));
 					scanPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}}]});
 					expect((await callType.func(Model.scan().exec).bind(Model.scan())()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie-get"}]);
 				});
 
 				it("Should return correct result for async get function on attribute", async () => {
-					Model = new dynamoose.Model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "get": async (val) => `${val}-get`}}));
+					Model = dynamoose.model("Cat", new dynamoose.Schema({"id": Number, "name": {"type": String, "get": async (val) => `${val}-get`}}));
 					scanPromiseResolver = () => ({"Items": [{"id": {"N": "1"}, "name": {"S": "Charlie"}}]});
 					expect((await callType.func(Model.scan().exec).bind(Model.scan())()).map((item) => ({...item}))).to.eql([{"id": 1, "name": "Charlie-get"}]);
 				});
diff --git a/test/Schema.js b/test/Schema.js
index 9e55dc1b..5bd24cdc 100644
--- a/test/Schema.js
+++ b/test/Schema.js
@@ -1,70 +1,70 @@
 const {expect} = require("chai");
-const Schema = require("../lib/Schema");
+const dynamoose = require("../lib");
 const Error = require("../lib/Error");
 
 describe("Schema", () => {
 	it("Should be a function", () => {
-		expect(Schema).to.be.a("function");
+		expect(dynamoose.Schema).to.be.a("function");
 	});
 
 	it("Should throw an error if not using `new` keyword", () => {
-		expect(() => Schema()).to.throw("Class constructor Schema cannot be invoked without 'new'");
+		expect(() => dynamoose.Schema()).to.throw("Class constructor Schema cannot be invoked without 'new'");
 	});
 
 	it("Should throw an error if nothing passed in", () => {
-		expect(() => new Schema()).to.throw("Schema initalization parameter must be an object.");
+		expect(() => new dynamoose.Schema()).to.throw("Schema initalization parameter must be an object.");
 	});
 
 	it("Should throw an error if empty object passed in", () => {
-		expect(() => new Schema({})).to.throw("Schema initalization parameter must not be an empty object.");
+		expect(() => new dynamoose.Schema({})).to.throw("Schema initalization parameter must not be an empty object.");
 	});
 
 	it("Shouldn't throw an error if object passed in", () => {
-		expect(() => new Schema({"id": String})).to.not.throw();
+		expect(() => new dynamoose.Schema({"id": String})).to.not.throw();
 	});
 
 	it("Should set correct settings value", () => {
-		expect(new Schema({"id": String}, {"saveUnknown": true}).settings).to.eql({"saveUnknown": true});
+		expect(new dynamoose.Schema({"id": String}, {"saveUnknown": true}).settings).to.eql({"saveUnknown": true});
 	});
 
 	it("Should set correct settings value default value of empty object", () => {
-		expect(new Schema({"id": String}).settings).to.eql({});
+		expect(new dynamoose.Schema({"id": String}).settings).to.eql({});
 	});
 
 	it("Should throw error if timestamps already exists in schema", () => {
-		expect(() => new Schema({"id": String, "createdAt": Date, "updatedAt": Date}, {"timestamps": true}).settings).to.throw("Timestamp attributes must not be defined in schema.");
-		expect(() => new Schema({"id": String, "created": Date, "updated": Date}, {"timestamps": {"createdAt": "created", "updatedAt": "updated"}}).settings).to.throw("Timestamp attributes must not be defined in schema.");
+		expect(() => new dynamoose.Schema({"id": String, "createdAt": Date, "updatedAt": Date}, {"timestamps": true}).settings).to.throw("Timestamp attributes must not be defined in schema.");
+		expect(() => new dynamoose.Schema({"id": String, "created": Date, "updated": Date}, {"timestamps": {"createdAt": "created", "updatedAt": "updated"}}).settings).to.throw("Timestamp attributes must not be defined in schema.");
 	});
 
 	it("Should throw error if passing multiple schema elements into array", () => {
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [String, Number]}})).to.throw("You must only pass one element into schema array.");
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("You must only pass one element into schema array.");
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [String, Number]}})).to.throw("You must only pass one element into schema array.");
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("You must only pass one element into schema array.");
 	});
 
 	it("Should not throw error if passing only one element into schema elements array", () => {
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [String]}})).to.not.throw();
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "data": {"type": Array, "schema": [String]}}}]}})).to.not.throw();
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [String]}})).to.not.throw();
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name": String, "data": {"type": Array, "schema": [String]}}}]}})).to.not.throw();
 	});
 
 	it("Should throw error if attribute names contain dots", () => {
-		expect(() => new Schema({"id.data": String})).to.throw("Attributes must not contain dots.");
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name.other": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes must not contain dots.");
+		expect(() => new dynamoose.Schema({"id.data": String})).to.throw("Attributes must not contain dots.");
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"name.other": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes must not contain dots.");
 	});
 
 	it.skip("Should throw error if attribute names only contains number", () => {
-		expect(() => new Schema({"1": String})).to.throw("Attributes names must not be numbers.");
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"1": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not be numbers.");
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"1": [String], "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not be numbers.");
+		expect(() => new dynamoose.Schema({"1": String})).to.throw("Attributes names must not be numbers.");
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"1": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not be numbers.");
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"1": [String], "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not be numbers.");
 	});
 
 	it.skip("Should throw error if attribute names contains star", () => {
-		expect(() => new Schema({"*": String})).to.throw("Attributes names must not include stars.");
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"*": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not include stars.");
-		expect(() => new Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"*": [String], "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not include stars.");
+		expect(() => new dynamoose.Schema({"*": String})).to.throw("Attributes names must not include stars.");
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"*": String, "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not include stars.");
+		expect(() => new dynamoose.Schema({"id": String, "friends": {"type": Array, "schema": [{"type": Object, "schema": {"*": [String], "data": {"type": Array, "schema": [Buffer, String]}}}]}})).to.throw("Attributes names must not include stars.");
 	});
 
 	it("Should not throw error if valid schema passed in", () => {
-		expect(() => new Schema({"id": Number, "friends": [String]})).to.not.throw();
+		expect(() => new dynamoose.Schema({"id": Number, "friends": [String]})).to.not.throw();
 	});
 
 	describe("getAttributeType", () => {
@@ -135,13 +135,13 @@ describe("Schema", () => {
 					let schema;
 					beforeEach(() => {
 						if (type === "standard") {
-							schema = new Schema({...schemaObj.schema});
+							schema = new dynamoose.Schema({...schemaObj.schema});
 						} else {
 							const schemaObject = {...schemaObj.schema};
 							Object.keys(schemaObject).forEach((key) => {
 								schemaObject[key] = {"type": schemaObject[key]};
 							});
-							schema = new Schema(schemaObject);
+							schema = new dynamoose.Schema(schemaObject);
 						}
 					});
 
@@ -165,21 +165,21 @@ describe("Schema", () => {
 
 	describe("getHashKey", () => {
 		it("Should return first attribute if no hash key defined", () => {
-			expect(new Schema({"id": String, "age": Number}).getHashKey()).to.eql("id");
+			expect(new dynamoose.Schema({"id": String, "age": Number}).getHashKey()).to.eql("id");
 		});
 
 		it("Should return hash key if set to true", () => {
-			expect(new Schema({"id": String, "age": {"type": Number, "hashKey": true}}).getHashKey()).to.eql("age");
+			expect(new dynamoose.Schema({"id": String, "age": {"type": Number, "hashKey": true}}).getHashKey()).to.eql("age");
 		});
 	});
 
 	describe("getRangeKey", () => {
 		it("Should return undefined if no range key defined", () => {
-			expect(new Schema({"id": String, "age": Number}).getRangeKey()).to.eql(undefined);
+			expect(new dynamoose.Schema({"id": String, "age": Number}).getRangeKey()).to.eql(undefined);
 		});
 
 		it("Should return range key if set to true", () => {
-			expect(new Schema({"id": String, "age": {"type": Number, "rangeKey": true}}).getRangeKey()).to.eql("age");
+			expect(new dynamoose.Schema({"id": String, "age": {"type": Number, "rangeKey": true}}).getRangeKey()).to.eql("age");
 		});
 	});
 
@@ -710,7 +710,7 @@ describe("Schema", () => {
 
 		tests.forEach((test) => {
 			it(test.name, async () => {
-				expect(await (new Schema(test.input).getCreateTableAttributeParams({"options": {"throughput": "ON_DEMAND"}}))).to.eql(test.output);
+				expect(await (new dynamoose.Schema(test.input).getCreateTableAttributeParams({"options": {"throughput": "ON_DEMAND"}}))).to.eql(test.output);
 			});
 		});
 	});
@@ -751,7 +751,7 @@ describe("Schema", () => {
 
 		tests.forEach((test) => {
 			it(test.name, () => {
-				expect(new Schema(test.input).attributes()).to.eql(test.output);
+				expect(new dynamoose.Schema(test.input).attributes()).to.eql(test.output);
 			});
 		});
 	});
@@ -765,26 +765,26 @@ describe("Schema", () => {
 
 		tests.forEach((test) => {
 			it(test.name, () => {
-				expect(new Schema({"id": String}, test.settings).getSettingValue(test.input)).to.eql(test.output);
+				expect(new dynamoose.Schema({"id": String}, test.settings).getSettingValue(test.input)).to.eql(test.output);
 			});
 		});
 	});
 
 	describe("getAttributeTypeDetails", () => {
 		it("Should throw for invalid attribute", () => {
-			const func = () => new Schema({"id": String}).getAttributeTypeDetails("random");
+			const func = () => new dynamoose.Schema({"id": String}).getAttributeTypeDetails("random");
 			expect(func).to.throw(Error.UnknownAttribute);
 			expect(func).to.throw("Invalid Attribute: random");
 		});
 
 		it("Should not throw for attribute with number in it (without . prefix)", () => {
-			const func = () => new Schema({"id": String, "ran2dom": String}).getAttributeTypeDetails("ran2dom");
+			const func = () => new dynamoose.Schema({"id": String, "ran2dom": String}).getAttributeTypeDetails("ran2dom");
 			expect(func).to.not.throw(Error.UnknownAttribute);
 			expect(func).to.not.throw("Invalid Attribute: ran2dom");
-		});		
+		});
 
 		it("Should have correct custom type for date", () => {
-			const functions = new Schema({"id": Date}).getAttributeTypeDetails("id").customType.functions;
+			const functions = new dynamoose.Schema({"id": Date}).getAttributeTypeDetails("id").customType.functions;
 			expect(functions.toDynamo).to.exist;
 			expect(functions.fromDynamo).to.exist;
 			expect(functions.toDynamo(new Date(1582246653000))).to.eql(1582246653000);
@@ -792,7 +792,7 @@ describe("Schema", () => {
 		});
 
 		it("Should have correct custom type for date with type object and no settings", () => {
-			const functions = new Schema({"id": {"type": {"value": Date}}}).getAttributeTypeDetails("id").customType.functions;
+			const functions = new dynamoose.Schema({"id": {"type": {"value": Date}}}).getAttributeTypeDetails("id").customType.functions;
 			expect(functions.toDynamo).to.exist;
 			expect(functions.fromDynamo).to.exist;
 			expect(functions.toDynamo(new Date(1582246653000))).to.eql(1582246653000);
@@ -800,7 +800,7 @@ describe("Schema", () => {
 		});
 
 		it("Should have correct custom type for date with custom storage settings as miliseconds", () => {
-			const functions = new Schema({"id": {"type": {"value": Date, "settings": {"storage": "miliseconds"}}}}).getAttributeTypeDetails("id").customType.functions;
+			const functions = new dynamoose.Schema({"id": {"type": {"value": Date, "settings": {"storage": "miliseconds"}}}}).getAttributeTypeDetails("id").customType.functions;
 			expect(functions.toDynamo).to.exist;
 			expect(functions.fromDynamo).to.exist;
 			expect(functions.toDynamo(new Date(1582246653000))).to.eql(1582246653000);
@@ -808,7 +808,7 @@ describe("Schema", () => {
 		});
 
 		it("Should have correct custom type for date with custom storage settings as seconds", () => {
-			const functions = new Schema({"id": {"type": {"value": Date, "settings": {"storage": "seconds"}}}}).getAttributeTypeDetails("id").customType.functions;
+			const functions = new dynamoose.Schema({"id": {"type": {"value": Date, "settings": {"storage": "seconds"}}}}).getAttributeTypeDetails("id").customType.functions;
 			expect(functions.toDynamo).to.exist;
 			expect(functions.fromDynamo).to.exist;
 			expect(functions.toDynamo(new Date(1582246653000))).to.eql(1582246653);
@@ -997,7 +997,7 @@ describe("Schema", () => {
 
 		tests.forEach((test) => {
 			it(test.name, async () => {
-				const schema = new Schema(test.schema);
+				const schema = new dynamoose.Schema(test.schema);
 				const output = await (schema.getAttributeSettingValue(...test.input));
 				if (typeof output !== "function") {
 					expect(output).to.eql(test.output);
diff --git a/test/Transaction.js b/test/Transaction.js
index cc98fbd4..db2f6cbc 100644
--- a/test/Transaction.js
+++ b/test/Transaction.js
@@ -4,7 +4,6 @@ chai.use(chaiAsPromised);
 const {expect} = chai;
 const dynamoose = require("../lib");
 const util = require("util");
-const Model = require("../lib/Model");
 const ModelStore = require("../lib/ModelStore");
 
 describe("Transaction", () => {
@@ -19,13 +18,13 @@ describe("Transaction", () => {
 	functionCallTypes.forEach((callType) => {
 		describe(callType.name, () => {
 			beforeEach(() => {
-				dynamoose.Model.defaults = {
+				dynamoose.model.defaults.set({
 					"create": false,
 					"waitForActive": false
-				};
+				});
 			});
 			afterEach(() => {
-				dynamoose.Model.defaults = {};
+				dynamoose.model.defaults.set({});
 				dynamoose.aws.ddb.revert();
 				ModelStore.clear();
 			});
@@ -58,7 +57,7 @@ describe("Transaction", () => {
 			});
 
 			it("Should throw error if model hasn't been created", () => {
-				new Model("User", {"id": Number, "name": String});
+				dynamoose.model("User", {"id": Number, "name": String});
 				return expect(callType.func(dynamoose.transaction)([{"Get": {"Key": {"id": {"N": "1"}}, "TableName": "User"}}, {"Get": {"Key": {"id": {"N": "2"}}, "TableName": "Credit"}}])).to.be.rejectedWith("Model \"Credit\" not found. Please register the model with dynamoose before using it in transactions.");
 			});
 
@@ -73,8 +72,8 @@ describe("Transaction", () => {
 					}
 				});
 
-				new Model("User", {"id": Number, "name": String});
-				new Model("Credit", {"id": Number, "name": String});
+				dynamoose.model("User", {"id": Number, "name": String});
+				dynamoose.model("Credit", {"id": Number, "name": String});
 				await callType.func(dynamoose.transaction)([{"Get": {"Key": {"id": {"N": "1"}}, "TableName": "User"}}, {"Get": {"Key": {"id": {"N": "2"}}, "TableName": "Credit"}}]);
 				expect(transactParams).to.eql({
 					"TransactItems": [
@@ -109,8 +108,8 @@ describe("Transaction", () => {
 					}
 				});
 
-				new Model("User", {"id": Number, "name": String});
-				new Model("Credit", {"id": Number, "name": String});
+				dynamoose.model("User", {"id": Number, "name": String});
+				dynamoose.model("Credit", {"id": Number, "name": String});
 				await callType.func(dynamoose.transaction)([{"Put": {"Key": {"id": {"N": "1"}}, "TableName": "User"}}, {"Put": {"Key": {"id": {"N": "2"}}, "TableName": "Credit"}}]);
 				expect(transactParams).to.eql({
 					"TransactItems": [
@@ -141,8 +140,8 @@ describe("Transaction", () => {
 					})
 				});
 
-				new Model("User", {"id": Number, "name": String});
-				new Model("Credit", {"id": Number, "name": String});
+				dynamoose.model("User", {"id": Number, "name": String});
+				dynamoose.model("Credit", {"id": Number, "name": String});
 				return expect(callType.func(dynamoose.transaction)([{"Get": {"Key": {"id": {"N": "1"}}, "TableName": "User"}}, {"Get": {"Key": {"id": {"N": "2"}}, "TableName": "Credit"}}]).then((res) => res.map((a) => ({...a})))).to.eventually.eql([
 					{"id": 1, "name": "Bob"},
 					{"id": 2, "name": "My Credit"}
@@ -156,8 +155,8 @@ describe("Transaction", () => {
 					})
 				});
 
-				new Model("User", {"id": Number, "name": String});
-				new Model("Credit", {"id": Number, "name": String});
+				dynamoose.model("User", {"id": Number, "name": String});
+				dynamoose.model("Credit", {"id": Number, "name": String});
 				return expect(callType.func(dynamoose.transaction)([{"Get": {"Key": {"id": {"N": "1"}}, "TableName": "User"}}, {"Get": {"Key": {"id": {"N": "2"}}, "TableName": "Credit"}}])).to.eventually.eql(null);
 			});
 
@@ -172,8 +171,8 @@ describe("Transaction", () => {
 					}
 				});
 
-				new Model("User", {"id": Number, "name": String});
-				new Model("Credit", {"id": Number, "name": String});
+				dynamoose.model("User", {"id": Number, "name": String});
+				dynamoose.model("Credit", {"id": Number, "name": String});
 				await callType.func(dynamoose.transaction)([{"Put": {"Key": {"id": {"N": "1"}}, "TableName": "User"}}, {"Put": {"Key": {"id": {"N": "2"}}, "TableName": "Credit"}}], {"type": "write"});
 				expect(transactParams).to.be.an("object");
 			});
@@ -189,8 +188,8 @@ describe("Transaction", () => {
 					}
 				});
 
-				new Model("User", {"id": Number, "name": String});
-				new Model("Credit", {"id": Number, "name": String});
+				dynamoose.model("User", {"id": Number, "name": String});
+				dynamoose.model("Credit", {"id": Number, "name": String});
 				await callType.func(dynamoose.transaction)([{"Put": {"Key": {"id": {"N": "1"}}, "TableName": "User"}}, {"Put": {"Key": {"id": {"N": "2"}}, "TableName": "Credit"}}], {"type": "get"});
 				expect(transactParams).to.be.an("object");
 			});