{"id":13834107,"url":"https://github.com/actionhero/ah-sequelize-plugin","last_synced_at":"2025-12-15T04:43:57.968Z","repository":{"id":15583161,"uuid":"18318837","full_name":"actionhero/ah-sequelize-plugin","owner":"actionhero","description":"sequelize plugin for actionhero","archived":false,"fork":false,"pushed_at":"2024-11-01T07:18:14.000Z","size":3153,"stargazers_count":36,"open_issues_count":13,"forks_count":23,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-07-08T08:47:18.078Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/actionhero.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-04-01T05:31:38.000Z","updated_at":"2024-08-01T15:29:31.000Z","dependencies_parsed_at":"2023-02-17T08:10:35.610Z","dependency_job_id":"85a4bc61-f1f6-46c6-ab89-ad0aace91fbd","html_url":"https://github.com/actionhero/ah-sequelize-plugin","commit_stats":{"total_commits":690,"total_committers":31,"mean_commits":"22.258064516129032","dds":0.4231884057971015,"last_synced_commit":"b5a726fc607156840f967118601e6a5c225618ce"},"previous_names":["evantahler/ah-sequelize-plugin"],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/actionhero/ah-sequelize-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/actionhero%2Fah-sequelize-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/actionhero%2Fah-sequelize-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/actionhero%2Fah-sequelize-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/actionhero%2Fah-sequelize-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/actionhero","download_url":"https://codeload.github.com/actionhero/ah-sequelize-plugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/actionhero%2Fah-sequelize-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265871815,"owners_count":23842073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T13:00:52.466Z","updated_at":"2025-12-15T04:43:57.891Z","avatar_url":"https://github.com/actionhero.png","language":"TypeScript","funding_links":[],"categories":["ORM and Datamapping","TypeScript"],"sub_categories":[],"readme":"![plugin](https://i.imgur.com/nd1btLt.png)\n\n# ah-sequelize-plugin\n\n[![CircleCI](https://circleci.com/gh/actionhero/ah-sequelize-plugin.svg?style=svg)](https://circleci.com/gh/actionhero/ah-sequelize-plugin)\n\nThis plugin connects [Sequelize](https://sequelize.org/) and [Actionhero](https://www.actionherojs.com). It handles running migrations and connecting your models. Under the hood, we use [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) and [Umzug](https://github.com/sequelize/umzug)\n\n## Notes\n\n- Versions `4.0.0+` of this package are only compatible with Actionhero versions `28.0.0+`, sequelize v6+ and sequelize-typescript v2+. Node.js v12+ is required.\n- Versions `3.0.0+` of this package are only compatible with Actionhero versions `24.0.0+`, sequelize v6+ and sequelize-typescript v2+. Node.js v10+ is required.\n- Versions `2.0.0+` of this package are only compatible with Actionhero versions `21.0.0+`.\n- Versions `1.0.0+` of this package are only compatible with Actionhero versions `18.0.0+`.\n\nFor versions compatible with ActionHero versions prior to `21.0.0`, use version [`1.x.x`](https://github.com/actionhero/ah-sequelize-plugin/releases/tag/v1.3.2).\nFor versions compatible with ActionHero versions prior to `18.0.0`, use version [`0.9.x`](https://github.com/actionhero/ah-sequelize-plugin/releases/tag/v0.9.0).\n\n## Setup\n\n1. Install this plugin: `npm install ah-sequelize-plugin --save`\n2. Add sequelize packages: `npm install sequelize@6 sequelize-typescript@2 --save`\n3. Add types and reflexive addons: `npm install @types/validator reflect-metadata --save`\n4. Add plugin to your project's `./src/config/plugins.ts`:\n\n```ts\nimport * as path from \"path\";\n\nexport const DEFAULT = {\n  plugins: () =\u003e {\n    return {\n      \"ah-sequelize-plugin\": {\n        path: path.join(process.cwd(), \"node_modules\", \"ah-sequelize-plugin\"),\n      },\n    };\n  },\n};\n```\n\n5. Add `experimentalDecorators` and `emitDecoratorMetadata` to your Typescript `tsconfig.json` file:\n\n```json\n{\n  \"compilerOptions\": {\n    \"outDir\": \"./dist\",\n    \"allowJs\": true,\n    \"module\": \"commonjs\",\n    \"target\": \"es2018\",\n    \"experimentalDecorators\": true, // \u003c-- required\n    \"emitDecoratorMetadata\": true // \u003c-- required\n  },\n  \"include\": [\"./src/**/*\"]\n}\n```\n\n### Add supported database packages\n\n- MySQL: `npm install mysql2 --save`\n- SQLite: `npm install sqlite3 --save`\n- Postgres: `npm install --save pg pg-hstore`\n- MSSql: `npm install --save tedious`\n\nFor additional information on supported databases visit the [Sequelize Docs](http://docs.sequelizejs.com/manual/installation/getting-started).\n\n### Install optional dependencies\n\n- For Sequelize CLI: `npm install --save-dev sequelize-cli`\n\n### Configuration\n\nA `./src/config/sequelize.ts` will need to be created for your project. The example below will parse the Environment variable `DATABASE_URL` for a `postgres` database, however you can configure your connection in many ways. You can connect to DB pools, configure read/write splitting and more with Sequelize options. This configuration also enabled `automigrate`, which means Actionhero will run your migrations for you at startup.\n\n```javascript\nimport { URL } from \"url\";\nimport { join } from \"path\";\nimport { Dialect } from \"sequelize\";\n\nconst namespace = \"sequelize\";\n\ndeclare module \"actionhero\" {\n  export interface ActionheroConfigInterface {\n    [namespace]: ReturnType\u003ctypeof DEFAULT[typeof namespace]\u003e;\n  }\n}\n\nconst databaseName = \"ah_sequelize\";\n\nexport const DEFAULT = {\n  [namespace]: (config) =\u003e {\n    let dialect = \"postgres\";\n    let host = process.env.DB_HOST || \"127.0.0.1\";\n    let port = process.env.DB_PORT || \"5432\";\n    let database =\n      process.env.DB_DATABASE ||\n      `${databaseName}_${config.process.env}${\n        process.env.JEST_WORKER_ID ? \"_\" + process.env.JEST_WORKER_ID : \"\"\n      }`;\n    let username =\n      process.env.DB_USER || process.env.CI ? \"postgres\" : undefined;\n    let password = process.env.DB_PASS || undefined;\n\n    // if your environment provides database information via a single JDBC-style URL like mysql://username:password@hostname:port/default_schema\n    const connectionURL =\n      process.env.DATABASE_URL || process.env.MYSQL_URL || process.env.PG_URL;\n\n    if (connectionURL) {\n      const parsed = new URL(connectionURL);\n      if (parsed.protocol) dialect = parsed.protocol.slice(0, -1);\n      if (parsed.username) username = parsed.username;\n      if (parsed.password) password = parsed.password;\n      if (parsed.hostname) host = parsed.hostname;\n      if (parsed.port) port = parsed.port;\n      if (parsed.pathname) database = parsed.pathname.substring(1);\n    }\n\n    if (dialect === \"postgresql\") dialect = \"postgres\";\n\n    return {\n      autoMigrate: true,\n      logging: false,\n      dialect: dialect as Dialect,\n      port: parseInt(port),\n      database: database,\n      host: host,\n      username: username,\n      password: password,\n      models: [join(__dirname, \"..\", \"models\")],\n      migrations: [join(__dirname, \"..\", \"migrations\")],\n      migrationLogLevel: \"info\",\n      // you can also pass \"dialectOptions\", for example if you need `{ssl: true}` for Postgres\n\n      // For Example, if you want to change the schema of a Postgres database away from \"public\", you would need to include the following configs:\n      // schema: schema,\n      // searchPath: schema,\n      // dialectOptions: { prependSearchPath: true },\n    };\n  },\n};\n\n// for the sequelize CLI tool\nmodule.exports.development = DEFAULT.sequelize({\n  env: \"development\",\n  process: { env: \"development\" },\n});\n\nmodule.exports.staging = DEFAULT.sequelize({\n  env: \"staging\",\n  process: { env: \"staging\" },\n});\n\nmodule.exports.production = DEFAULT.sequelize({\n  env: \"production\",\n  process: { env: \"production\" },\n});\n```\n\n#### A Note about Postgres Schema changes\n\nThe configuration above includes the 3 changes you need in your configuration to choose a non default (e.g.: `public`) schema for a Postgres database: `schema`, `searchPath`, and `dialectOptions`. This package also includes the required code to patch your migrations (more on this below) to use the proper schema with no additional changes without any additional changes needed to your migrations or models.\n\n#### Configuring sequelize-cli\n\nIf you installed the CLI in the last step, you'll want to do the following to finish setting it up:\n\nCreate a file `.sequelizerc` in the root of your project. It should contain:\n\n```javascript\nconst path = require(\"path\");\n\nmodule.exports = {\n  config: path.resolve(\".\", \"sequelize.js\"),\n  \"models-path\": path.resolve(\"src\", \"models\"),\n  \"seeders-path\": path.resolve(\"src\", \"seeders\"),\n  \"migrations-path\": path.resolve(\"src\", \"migrations\"),\n};\n```\n\nThis tells the sequelize-cli where to find your migration files, models, etc. The values here assume you are using the default configuration.\n\nIn the root folder create a file called `sequelize.js`, and add the following contents\n\n```javascript\nconst sequelizeConfig = require(\"./dist/config/sequelize.js\"); // be sure to compile your project first.  Alterativly you could use `ts-node` and incldue the `./src/config/sequelize.ts`\n\nconst sequelizeConfigEnv =\n  sequelizeConfig[process.env.NODE_ENV] || sequelizeConfig.DEFAULT;\nmodule.exports = sequelizeConfigEnv.sequelize();\n```\n\nThis initializes the config for the CLI to use.\n\nOnce you're done, the folder structure should look like so:\n\n```\nsrc/\n  models/\n  migrations/\n.sequelizerc\nsequelize.js\n```\n\nYou can now use the CLI to create \u0026 run migrations:\n\n```\nnpx sequelize-cli migration:generate --name migration-skeleton\n```\n\n#### Logging\n\nThe `logging` configuration parameter accepts either a `false` value, or a function which accepts a log value of type `string` and a event level value of type `string` (ex: `console.log`, `log` from Actionhero). If you are passing in a function for the logging parameter.\n\n## Models\n\nThanks to `sequelize-typescript`, we can have models with tagged parameters. The example below shows of how to use hooks, associations, and more. Further information can be found at https://github.com/RobinBuschmann/sequelize-typescript.\n\n```ts\n// from `src/models/Users.ts`\nimport * as bcrypt from \"bcrypt\";\nimport {\n  Model,\n  Table,\n  Column,\n  AllowNull,\n  IsEmail,\n  BeforeCreate,\n  HasMany,\n} from \"sequelize-typescript\";\nimport * as uuid from \"uuid/v4\";\nimport { Post } from \"./Post\";\n\n@Table({ tableName: \"users\", paranoid: true })\nexport class User extends Model\u003cUser\u003e {\n  saltRounds = 10;\n\n  @Column({ primaryKey: true })\n  guid: string;\n\n  @AllowNull(false)\n  @Column\n  firstName: string;\n\n  @AllowNull(false)\n  @Column\n  lastName: string;\n\n  @AllowNull(false)\n  @IsEmail\n  @Column\n  email: string;\n\n  @Column\n  passwordHash: string;\n\n  @HasMany(() =\u003e Post)\n  posts: Post[];\n\n  @BeforeCreate\n  static generateGuid(instance) {\n    if (!instance.guid) {\n      instance.guid = uuid();\n    }\n  }\n\n  async updatePassword(password: string) {\n    this.passwordHash = await bcrypt.hash(password, this.saltRounds);\n    await this.save();\n  }\n\n  async checkPassword(password: string) {\n    if (!this.passwordHash) {\n      throw new Error(\"password not set for this team member\");\n    }\n\n    const match = await bcrypt.compare(password, this.passwordHash);\n    return match;\n  }\n}\n```\n\nYou can then use these models in your Actions, Tasks, etc, by simply requiring them.\n\n```ts\n// from actions/user.ts\n\nimport { Action, ParamsFrom } from \"actionhero\";\nimport { User } from \"./../models/User\";\n\nexport class UserCreate extends Action {\n  name = \"user:create\";\n  description = \"create a new user\";\n  inputs = {\n    firstName: { required: true },\n    lastName: { required: true },\n    password: { required: true },\n    email: { required: true },\n  };\n\n  async run({ params }: {params: ParamsFrom\u003cUserCreate\u003e) {\n    const user = new User({\n      firstName: params.firstName,\n      lastName: params.lastName,\n      email: params.email,\n    });\n    await user.save();\n    await user.updatePassword(params.password);\n    return { userId: user.id }\n  }\n}\n```\n\n## [Migrations](http://docs.sequelizejs.com/en/latest/api/migrations)\n\nThis plugin does not condone the use of `Sequelize.sync()` in favor of migrations. Keep you migrations in `./migrations` and use the [sequelize-cli](https://github.com/sequelize/cli) to execute them.\n\nAn example migration to create a `users` table would look like:\n\n```ts\n// from ./migrations/0000001-createUsersTable.ts\n\nimport * as Sequelize from \"sequelize\";\n\nexport default {\n  up: async function (\n    queryInterface: Sequelize.QueryInterface,\n    DataTypes: typeof Sequelize\n  ) {\n    await queryInterface.createTable(\n      \"users\",\n      {\n        guid: {\n          type: DataTypes.UUID,\n          defaultValue: DataTypes.UUIDV4,\n          primaryKey: true,\n        },\n\n        firstName: {\n          type: DataTypes.STRING(191),\n          allowNull: false,\n        },\n\n        lastName: {\n          type: DataTypes.STRING(191),\n          allowNull: false,\n        },\n\n        email: {\n          type: DataTypes.STRING(191),\n          allowNull: false,\n        },\n\n        passwordHash: {\n          type: DataTypes.TEXT,\n          allowNull: true,\n        },\n\n        lastLoginAt: {\n          type: DataTypes.DATE,\n          allowNull: true,\n        },\n\n        createdAt: DataTypes.DATE,\n        updatedAt: DataTypes.DATE,\n        deletedAt: DataTypes.DATE,\n      },\n      {\n        charset: \"utf8mb4\",\n      }\n    );\n\n    await queryInterface.addIndex(\"users\", [\"email\"], {\n      unique: true,\n      fields: [\"email\"],\n    });\n  },\n\n  down: async function (queryInterface: Sequelize.QueryInterface) {\n    await queryInterface.dropTable(\"users\");\n  },\n};\n```\n\nYou can use the [sequelize-cli](http://docs.sequelizejs.com/en/latest/docs/migrations/) to create and execute migrations.\n\nBy default, `ah-sequelize-plugin` will automatically execute any pending migrations when Actionhero starts up. You can disable this behavior by adding `autoMigrate: false` to your sequelize config.\n\n## Fixtures (removed)\n\nAs of version `2.0.0`, we have removed support for fixtures from this plugin. If you need to load data into your application consider an Initializer in your project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Factionhero%2Fah-sequelize-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Factionhero%2Fah-sequelize-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Factionhero%2Fah-sequelize-plugin/lists"}