orm-modeling is a robust Node.js ORM tool designed with TypeScript. It enables you to define your database schemas using JavaScript objects, with the added benefit of IDE autocompletion and type-checking for model definitions. Built on the Knex query builder, it offers compatibility with a variety of database engines.
Key Features:
- Define Knex schemas from models with TypeScript's autocompletion and type-checking capabilities.
- Generate Markdown documentation from models.
- Generate TypeScript interfaces for data entities from models.
- Future updates will add support for other Node.js ORM modules.
# To install orm-modeling
npm install orm-modeling
# You will also need to install Knex and your chosen database engine, for example MySQL
npm install knex mysql
What you need to do is to create a Knex instance and define your model. Then, pass these to the createKnexSchema
function, which will return a Knex instance with the schema applied.
import { createKnexSchema, Model } from 'orm-modeling';
import Knex, { Knex as KnexType } from 'knex';
// Create a Knex instance
const db: KnexType = Knex();
// Define your model
const model: Model = {
// ... model attributes go here
};
createKnexSchema({db, model}).then((db: KnexType) => {
// The function returns the Knex instance
});
- Models should be defined according to the TypeScript types provided. Thanks to TypeScript, your IDE will be able to provide useful prompts and indications as you define your models.
- Refer to this TypeScript example for a model definition.
In orm-modeling, a model is a representation of a database table and its associated attributes. Models are defined as JavaScript objects, taking advantage of TypeScript's autocompletion and type-checking capabilities to ensure correct model definitions.
Here's an example of how you can define a model for a 'files' table:
import {DataTypes, Model} from 'orm-modeling';
/**
* File model
*/
const model: Model = {
tableName: 'files',
autoId: true,
timestamps: {
makeDefaultNow: true
},
comment: 'File archives',
indexes: [],
columns: {
name: {
type: DataTypes.VARCHAR,
length: 500,
unique: true,
nullable: false,
comment: 'File name',
},
original_filename: {
type: DataTypes.VARCHAR,
length: 2000,
nullable: false,
comment: 'Original name'
},
mimetype: {
type: DataTypes.VARCHAR,
length: 256,
nullable: false,
comment: 'File type',
},
size: {
type: DataTypes.BIG_INTEGER,
nullable: false,
comment: 'File size',
},
data: {
type: DataTypes.LONG_BLOB,
comment: 'File data',
},
creator_id: {
type: DataTypes.INTEGER,
unsigned: true,
nullable: false,
comment: 'Creator id, admin user.'
},
// ... columns go here
}
};
export default model;
In this example, the Model
object has several properties:
tableName
: The name of the table in the database.autoId
: If set to true, an 'id' column of type 'integer' will be automatically added to the model.timestamps
: If set to true, 'created_at' and 'updated_at' columns will be automatically added to the model. You can also pass an object with more specific configuration options.comment
: A comment for the table.indexes
: An array defining the indexes for the table.columns
: An object defining the columns of the table. Each key in this object represents a column in the table, and the value is an object that defines the properties of the column.
The columns
property is an object where each key-value pair represents a column in the table. The key is the column name, and the value is an object that defines the column properties.
Let's delve into the Column
interface. Each property in the Column
interface represents a configuration option for a column in a database table.
-
type
: This property defines the data type of the column. It can be one of the values from theDataTypes
enum, or a string representing a valid data type. TheDataTypes
enum includes common data types such as 'string', 'integer', 'date', 'boolean', etc. -
autoIncrement
: If set totrue
or 'bigIncrements', the column will automatically increment its value for each new row. This is typically used for primary key columns. -
length
: This property specifies the maximum length of the column. It's applicable for string data types. -
unsigned
: If set totrue
, the column will be set as an unsigned integer. This means it can only hold non-negative numbers. This property only applies to integer fields. -
nullable
: If set totrue
, the column will allow null values. If not specified or set tofalse
, the column will not accept null values. -
primaryKey
: If set totrue
or a string, the column will be set as the primary key of the table. If the value is a string, it will be used as the name of the primary key constraint. -
unique
: If set totrue
or a string, a unique constraint will be added to this column. If the value is a string, it will be used as the name of the unique constraint. -
comment
: This property allows you to add a comment to the column. -
defaultValue
: This property allows you to set a default value for the column. -
datetimeOptions
: This property allows you to set options for 'datetime' and 'timestamp' column types. It should be an object of typeDatetimeOptions
, which can have properties likeprecision
anduseTz
(for timezone). -
floatOptions
: This property allows you to set options for 'float' and 'decimal' column types. It should be an object of typeFloatOptions
, which can have properties likeprecision
andscale
. -
enumType
: This property allows you to set options for 'enum' or 'enu' column types. It should be an object of typeEnumType
, which includesenumValues
(an array of possible values for the enum) andenumOptions
(additional options for the enum). -
reference
: This property allows you to add a foreign key reference to the column. It should be an object of typeReference
, which includes properties liketable
(the referenced table),column
(the referenced column), andforeignKeyName
(the name of the foreign key constraint).
Each of these properties allows you to fine-tune the behavior and characteristics of your database columns, providing a high degree of flexibility in defining your data models.
By following this guide, you can define complex models that accurately represent your database tables. Remember, the power of orm-modeling lies in its ability to leverage TypeScript's features, providing you with autocompletion and type-checking capabilities as you define your models.
For a complete example, refer to this Knex schema creation example.
- Import the
toMarkdownTable
function from theorm-modeling
library.
import { toMarkdownTable } from 'orm-modeling';
- Define your model object as per the
Model
interface.
const model: Model = {
// ... model definition goes here
};
- Call the
toMarkdownTable
function with your model object. This will return a string containing a Markdown table.
const markdown: string = toMarkdownTable(model);
- You can then write this string to a Markdown file, or use it however you like.
import { writeFileSync } from 'fs';
writeFileSync('model.md', markdown);
- Import the
toTypeScriptInterface
function from theorm-modeling
library.
import { toTypeScriptInterface } from 'orm-modeling';
- Define your model object as per the
Model
interface.
const model: Model = {
// ... model definition goes here
};
- Call the
toTypeScriptInterface
function with your model object. This will return a string containing a TypeScript interface.
const interfaceStr: string = toTypeScriptInterface(model);
- You can then write this string to a TypeScript file, or use it however you like.
import { writeFileSync } from 'fs';
writeFileSync('model.ts', interfaceStr);
This will generate a TypeScript interface that describes the structure of a row in the table that your model represents. This can be very useful when you're writing TypeScript code that interacts with this table, as it allows your editor to provide autocompletion and type checking.
For TypeScript users, if you encounter issues with the type declarations of certain packages, you may need to enable skipLibCheck
in your tsconfig.json:
{
"compilerOptions": {
"skipLibCheck": true
}
}