PageSourceSearch

https://sequelize.org/assets/js/2fe38759.af8f936f.js

js sequelize.org collected 2026-09-24 08:28:54 UTC 7,723 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunk=globalThis.webpackChunk||[]).push([[6022],{44550(e,n,i){i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"models/advanced","title":"Advanced model definitions","description":"Prevent creating a default PK attribute","source":"@site/docs/models/advanced.mdx","sourceDirName":"models","slug":"/models/advanced","permalink":"/docs/v7/models/advanced","draft":false,"unlisted":false,"editUrl":"https://github.com/sequelize/website/tree/main/docs/models/advanced.mdx","tags":[],"version":"current","lastUpdatedBy":"renovate[bot]","lastUpdatedAt":1775795365000,"sidebarPosition":9,"frontMatter":{"sidebar_position":9},"sidebar":"tutorialSidebar","previous":{"title":"Typing your Model (TypeScript)","permalink":"/docs/v7/models/model-typing"},"next":{"title":"Optimistic Locking","permalink":"/docs/v7/models/optimistic-locking"}}');var s=i(74848),o=i(28453);const d={sidebar_position:9},l="Advanced model definitions",a={},r=[{value:"Prevent creating a default PK attribute",id:"prevent-creating-a-default-pk-attribute",level:2},{value:"Caveat with minification",id:"caveat-with-minification",level:2},{value:"Engines",id:"engines",level:2},{value:"Table comments",id:"table-comments",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"advanced-model-definitions",children:"Advanced model definitions"})}),"\n",(0,s.jsx)(n.h2,{id:"prevent-creating-a-default-pk-attribute",children:"Prevent creating a default PK attribute"}),"\n",(0,s.jsxs)(n.p,{children:["By default, Sequelize automatically adds the primary key attribute ",(0,s.jsx)(n.code,{children:"id"})," to every model when no primary key has been defined manually.\nTo prevent this you can set the ",(0,s.jsx)(n.a,{href:"pathname:///api/v7/interfaces/_sequelize_core.index.ModelOptions.html#noPrimaryKey",children:(0,s.jsx)(n.code,{children:"noPrimaryKey"})})," option to true when defining the model."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:"@Table({ noPrimaryKey: true })\nexport class User extends Model {}\n"})}),"\n",(0,s.jsx)(n.p,{children:"If you want to prevent the addition of the default primary key for every model, you can also configure this option globally:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"class User extends Model {}\n\nconst sequelize = new Sequelize({\n  dialect: SqliteDialect,\n  define: {\n    noPrimaryKey: true,\n  },\n  models: [User],\n});\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Instances without primary keys can still be retrieved using ",(0,s.jsx)(n.code,{children:"Model.findOne"})," and ",(0,s.jsx)(n.code,{children:"Model.findAll"}),"."]}),"\n",(0,s.jsxs)(n.admonition,{type:"caution",children:[(0,s.jsxs)(n.p,{children:["Some model methods require a primary key to be defined. For instance, ",(0,s.jsx)(n.code,{children:"Model.findByPk"})," will throw an error if no primary key is defined."]}),(0,s.jsxs)(n.p,{children:["If your model has no primary keys, you need to use the static equivalent of the following instance methods, and provide your own ",(0,s.jsx)(n.code,{children:"where"})," parameter:"]}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"instance.save"}),": ",(0,s.jsx)(n.code,{children:"Model.update"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"instance.update"}),": ",(0,s.jsx)(n.code,{children:"Model.update"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"instance.reload"}),": ",(0,s.jsx)(n.code,{children:"Model.findOne"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"instance.destroy"}),": ",(0,s.jsx)(n.code,{children:"Model.destroy"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"instance.restore"}),": ",(0,s.jsx)(n.code,{children:"Model.restore"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"instance.decrement"}),": ",(0,s.jsx)(n.code,{children:"Model.decrement"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"instance.increment"}),": ",(0,s.jsx)(n.code,{children:"Model.increment"})]}),"\n"]})]}),"\n",(0,s.jsx)(n.h2,{id:"caveat-with-minification",children:"Caveat with minification"}),"\n",(0,s.jsx)(n.p,{children:"When defining a model, the name of the model will, by default, be the name of your class."}),"\n",(0,s.jsxs)(n.p,{children:["If you minify your code, the class name \u2014 and therefore its model name \u2014 may be changed by your minifier.\nThis can be an issue, as many systems use your modelName, from ",(0,s.jsx)(n.a,{href:"pathname:///api/v7/classes/_sequelize_core.index.Sequelize.html#models",children:"sequelize.models"}),"\nto ",(0,s.jsx)(n.a,{href:"/docs/v7/models/naming-strategies",children:"the name of the table associated to the model"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The solution to prevent this issue is to explicitly set the ",(0,s.jsx)(n.code,{children:"modelName"})," option:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:"// by specifying 'modelName' explicitely, the name of this model can be safely minified.\n@Table({ modelName: 'User' })\nexport class User extends Model {}\n"})}),"\n",(0,s.jsx)(n.h2,{id:"engines",children:"Engines"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"This feature is only available in MySQL & MariaDB"})}),"\n",(0,s.jsx)(n.p,{children:"The default engine for a model is InnoDB."}),"\n",(0,s.jsxs)(n.p,{children:["You can change the engine for a model with the ",(0,s.jsx)(n.code,{children:"engine"})," option (e.g., to MyISAM):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"const Person = sequelize.define(\n  'person',\n  {\n    /* attributes */\n  },\n  {\n    engine: 'MYISAM',\n  },\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Like every option for the definition of a model, this setting can also be changed globally with the ",(0,s.jsx)(n.code,{children:"define"})," option of the Sequelize constructor:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"const sequelize = new Sequelize({\n  /* options */\n  define: { engine: 'MYISAM' },\n});\n"})}),"\n",(0,s.jsx)(n.h2,{id:"table-comments",children:"Table comments"}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"This feature is only available in MySQL, MariaDB and PostgreSQL"})}),"\n",(0,s.jsxs)(n.p,{children:["You can use the ",(0,s.jsx)(n.code,{children:"comment"})," model option to set a comment on the table, which will be added to the table definition in SQL."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"import { Model } from '@sequelize/core';\nimport { Table } from '@sequelize/core/decorators-legacy';\n\n@Table({\n  // highlight-next-line\n  comment: 'This is the User model',\n})\nexport class User extends Model {}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453(e,n,i){i.d(n,{R:()=>d,x:()=>l});var t=i(96540);const s={},o=t.createContext(s);function d(e){const n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.