All Projects → Wsiegenthaler → sequelize-embed

Wsiegenthaler / sequelize-embed

Licence: BSD-3-Clause license
Easily insert and update sequelize models with deeply nested associations

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to sequelize-embed

graphcraft
Rapildy build and extend GraphQL API based on Sequelize models. This library helps you focus on business logic while taking care of GraphQL schema automatically.
Stars: ✭ 50 (+233.33%)
Mutual labels:  sequelize, sequelize-models
Sequelize Auto Migrations
Migration generator && runner for sequelize
Stars: ✭ 233 (+1453.33%)
Mutual labels:  sequelize
Sequelize Transparent Cache
Simple to use and universal cache layer for Sequelize
Stars: ✭ 137 (+813.33%)
Mutual labels:  sequelize
Connect Session Sequelize
Sequelize SessionStore for Express/Connect
Stars: ✭ 179 (+1093.33%)
Mutual labels:  sequelize
Sequelize Ui
Browser-based GUI for previewing and generating Sequelize project files.
Stars: ✭ 142 (+846.67%)
Mutual labels:  sequelize
Crate
👕 👖 📦 A sample web and mobile application built with Node, Express, React, React Native, Redux and GraphQL. Very basic replica of stitchfix.com / krate.in (allows users to get monthly subscription of trendy clothes and accessories).
Stars: ✭ 2,281 (+15106.67%)
Mutual labels:  sequelize
Forest Express Sequelize
🌱 Express/Sequelize Liana for Forest Admin
Stars: ✭ 134 (+793.33%)
Mutual labels:  sequelize
TypeScript-in-Nodejs-Starter
A starter kit for Node.js project written with TypeScript.
Stars: ✭ 39 (+160%)
Mutual labels:  sequelize
Express Starter
It's a hackathon-starter fork, but designed to use PostgreSQL by default (or MySQL)
Stars: ✭ 215 (+1333.33%)
Mutual labels:  sequelize
Next Postgres Sequelize
React 16.8.4 + NextJS 8.0.3 + Emotion + Sequelize 5/Postgres + Passport Local Auth + Google App Engine or Heroku Deployment
Stars: ✭ 176 (+1073.33%)
Mutual labels:  sequelize
Feathers Sequelize
A Feathers service adapter for the Sequelize ORM. Supporting MySQL, MariaDB, Postgres, SQLite, and SQL Server
Stars: ✭ 176 (+1073.33%)
Mutual labels:  sequelize
Node Express Postgresql Sequelize
Node.js, Express.js, Sequelize.js and PostgreSQL RESTful API
Stars: ✭ 148 (+886.67%)
Mutual labels:  sequelize
Sequelize Auto
Automatically generate bare sequelize models from your database.
Stars: ✭ 2,494 (+16526.67%)
Mutual labels:  sequelize
Koa2 Blog
第一个web项目,仿照cnode,欢迎新建账号试用
Stars: ✭ 141 (+840%)
Mutual labels:  sequelize
Sequelize Docs Zh Cn
Sequelize 文档的中文版本: v4.42.0 | v5.21.5 | v6.6.5
Stars: ✭ 2,745 (+18200%)
Mutual labels:  sequelize
Open Rest
Standard rest server, Base on restify and sequelize
Stars: ✭ 136 (+806.67%)
Mutual labels:  sequelize
Finale
Create flexible REST endpoints and controllers from Sequelize models in your Express app
Stars: ✭ 167 (+1013.33%)
Mutual labels:  sequelize
Cli
The Sequelize CLI
Stars: ✭ 2,248 (+14886.67%)
Mutual labels:  sequelize
nestjs-api-mongoose
Collection example apps with NestJS and Typeorm, Sequelize, Mongodb, PostgreSQL, MySQL, GraphQL, Mercurius, etc. for the NestJS community 😻
Stars: ✭ 153 (+920%)
Mutual labels:  sequelize
Typescript Express Starter
🚀 TypeScript Express Starter
Stars: ✭ 238 (+1486.67%)
Mutual labels:  sequelize

sequelize-embed

npm version Build Status dependencies Status Coverage Status Known Vulnerabilities License FOSSA Status

Easily insert and update sequelize models with deeply nested associations

While Sequelize will retrieve nested assocations via the include option, it does not provide the ability to write them. This module allows for easy synchronization of nested associations by recursively inserting new, updating existing, or deleting removed association values.

  • Synchronizes nested associations in a single atomic operation
  • Prunes redundant foreign keys and later infers them
  • Works with optimistic locking in Sequelize v4
  • Includes Epilogue middleware for document-oriented PUT/POST

API

Operations

insert(model, values, include, options)

Inserts a new record given values and synchronizes nested associations specified by include.

update(model, values, include, options)

Updates the record corresponding to values and synchronizes nested associations specified by include.

Parameters

model

The sequelize model of the root of the structure.

values

Object representing the values to be written, including any nested structure.

include

Array specifying the nested associations to be embedded. The include parameter is recursive and is usually a subset of those passed to Model.findById/One/All.

options

transaction

The transaction to be used. When provided, invoking commit or rollback is the resonsibility of the caller. Otherwise, a transaction will be created automatically and committed when done.

reload

Whether to reload and return the full instance after success. May also be an object specifying further options:

include

The nested associations to be read and returned. Defaults to the include parameter used in the write.

plain

Return plain object instead of Sequelize instances. (default true)

prune

Whether to prune redundant foreign keys. (default true)

Getting Started

Install

npm install --save sequelize-embed

Basic Example

Import sequelize-embed and initialize with sequelize:

const embed = require('sequelize-embed')(sequelize)

Setup an example schema - an Order can have Items, each of which is assigned a Department:

const Order = sequelize.define('Order', {})
const Item = sequelize.define('Item', { quantity: Sequelize.STRING })
const Department = sequelize.define('Department', { name: Sequelize.STRING })

Order.Items = Order.hasMany(Item, { as: 'items', foreignKey: 'orderId' })
Item.Department = Item.belongsTo(Department, { as: 'department', foreignKey: 'deptId' })`

Use the mkInclude helper to define the associations we wish to include. Here itemsOnly will update Items while itemsAndDept will update Items and Departments.

const { mkInclude } = embed.util.helpers

const itemsAndDept = [ mkInclude(Order.Items, mkInclude(Item.Department)) ]
const itemsOnly = [ mkInclude(Order.Items) ]

Insert an order, it's items, and departments by including itemsAndDept:

const order = {
  items: [ { quantity: 1, department: { name: 'produce' } } ]
}

embed.insert(Order, order, itemsAndDept)

// id: 1,
// items: [ { id: 1, quantity: '1', department: { id: 1, name: 'produce' } } ]

Change the quantity and department of our existing item:

const order = {
  id: 1,
  items: [ { id: 1, quantity: 2, department: { name: 'dairy' } } ]
}

embed.update(Order, order, itemsAndDept)

// id: 1,
// items: [ { id: 1, quantity: '2', department: { id: 2, name: 'dairy' } } ]

For the purposes of demonstration we've included Departments in our update, but since a Department is shared between orders we probably wouldn't want to include them when updating an order. Let's add another item, this time including just itemsOnly and being sure to specify a department known to exist:

const order = {
  id: 1,
  items: [
    { id: 1, quantity: 2, department: { id: 2, name: 'dairy' } },
    { quantity: 3, department: { id: 1 } } ]
}

embed.update(Order, order, itemsOnly, { reload: { include: itemsAndDept } })

// id: 1,
// items: [
//   { id: 1, quantity: '2', department: { id: 2, name: 'dairy' } },
//   { id: 2, quantity: '3', department: { id: 1, name: 'produce' } } ]

Notice that the new item was correctly assigned to the produce department despite Departments not being included in the update. Since belongs to foreign keys are on the source, they are always mapped back from any embedded values, even if a value isn't included for update itself. Also, we now pass itemsAndDept as the reload.include option which will include the department field in the result despite it not being updated.

Finally, remove the first item and reassign the second to the dairy department:

const order = {
  id: 1,
  items: [ { id: 2, quantity: 3, department: { id: 2 } } ]
}

embed.update(Order, order, itemsOnly, { reload: { include: itemsAndDept } })

// id: 1,
// items: [
//   { id: 2, quantity: '3', department: { id: 2, name: 'dairy' } } ]

Performance

Since the underlying data is normalized, completing an update or insert operation requires many reads and writes to synchronize the entire structure. For applications where performance is critical, be sure to restrict the total number of embedded associations and only embed those with reasonably low-cardinality.

Epilogue Middleware

Sequelize Embed also provides Epilogue middleware for automatically updating associations during PUT and POST operations. This can greatly simplify client development by giving your REST api the feel of a document-oriented database.

const embed = require('sequelize-embed')(sequelize)

const includeOnRead = ...  // include for get
const includeOnWrite = ... // include for put/post

// setup resource like normal
const resource = epilogue.resource({
  model: Model,
  include: includeOnRead,
  associations: false,
  ...
});

// add middleware to the resource, specifying includes
const middleware = embed.Epilogue(epilogue)
resource.use(middleware(includeOnWrite))

License

Everything in this repo is BSD License unless otherwise specified

sequelize-embed (c) 2017 Weston Siegenthaler

FOSSA Status

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].