需要自定义Sequelize Postgres数据类型的工作示例

时间:2019-05-12 22:14:47

标签: postgresql sequelize.js

我想在Sequelize中使用Postgres中的自定义类型。我已经基于Sequelize文档中的示例编写了代码,除了调用了在Sequelize或其他地方找不到的函数(“继承”)。但是,使用sequelize.define创建具有此自定义类型属性的模型会在Sequelize内部引发异常。我的代码中是否有突出的错误?还是有另一个很好的示例或教程来实现自定义数据类型?此外,文档示例中显示的“继承”功能是怎么回事-文档是否忽略了导入/需求,或者该调用是错误的?

我关注的文档在这里:http://docs.sequelizejs.com/manual/data-types.html#extending-datatypes

Postgres中定义的类型:

CREATE TYPE public.measurement AS
(
    unit text,
    value double precision
);

我在NodeJS中的测试代码:

const Sequelize = require('sequelize');

let dataTypes = Sequelize.DataTypes;

// Create class for custom datatype
class MEASUREMENT extends dataTypes.ABSTRACT {
    toSql() {
        console.log('MEASUREMENT toSql');
        return 'MEASUREMENT';
    }
    static parse(value) {
        console.log('MEASUREMENT parse value=', value);
        return value;
    }
};

// Set key
MEASUREMENT.prototype.key = 'MEASUREMENT';
MEASUREMENT.key = MEASUREMENT.prototype.key;

// Add to DataTypes
dataTypes.MEASUREMENT = MEASUREMENT;

// Add to Sequelize
Sequelize.MEASUREMENT = Sequelize.Utils.classToInvokable(MEASUREMENT);

let pgTypes = dataTypes.postgres;

// Map dialects
dataTypes.MEASUREMENT.types.postgres = ['MEASUREMENT']

pgTypes.MEASUREMENT = function MEASUREMENT() {
    if (!(this instanceof pgTypes.MEASUREMENT)) return new pgTypes.MEASUREMENT();
    DataTypes.MEASUREMENT.apply(this, arguments);
}

// inherits(pgTypes.MEASUREMENT, dataTypes.MEASUREMENT);
// Node throws a parse error. This is in the example in the Sequelize docs, however.

pgTypes.MEASUREMENT.parse = dataTypes.MEASUREMENT.parse;


// ------------------------------

const sequelize = new Sequelize('test', 'test', 'test', {
    host: 'localhost',
    dialect: 'postgres'
});

const Thing = sequelize.define('thing', {
    name: Sequelize.STRING,
    weight: Sequelize.MEASUREMENT
});

运行时调用堆栈:

C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:48
        if (dataType.types[this.dialectName]) {                                                                         
                          ^                                                                                             

TypeError: Cannot read property 'postgres' of undefined                                                                 
    at _.each.dataType (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:48:27)                                                                                                                   
    at C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:4911:15                                                
    at baseForOwn (C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:2996:24)                                   
    at C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:4880:18                                                
    at Function.forEach (C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:9344:14)                             
    at ConnectionManager.refreshTypeParser (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:46:7)                                                                                                
    at new ConnectionManager (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\postgres\connection-manager.js:23:10)                                                                                                             
    at new PostgresDialect (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\postgres\index.js:14:30)    
    at new Sequelize (C:\Workspaces\nebula\server\node_modules\sequelize\lib\sequelize.js:320:20)                       
    at Object.<anonymous> (C:\Workspaces\nebula\server\testsequelizecustom.js:58:19)                                    
    at Module._compile (internal/modules/cjs/loader.js:689:30)                                                          
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)                                            
    at Module.load (internal/modules/cjs/loader.js:599:32)                                                              
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)                                                            
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)                                                     
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)                                                  
    at startup (internal/bootstrap/node.js:279:19)                                                                      
    at bootstrapNodeJSCore (internal/bootstrap/node.js:752:3)                                                           

1 个答案:

答案 0 :(得分:0)

就在您已经拥有的行下:

pgTypes.MEASUREMENT.parse = dataTypes.MEASUREMENT.parse;

添加以下行,错误就会消失:

pgTypes.MEASUREMENT.types = {postgres:[‘MEASUREMENT’]};

您可能还需要添加此行,以处理相关的错误(请参见下文)。

dataTypes.postgres.MEASUREMENT.key = ‘MEASUREMENT’;

相关错误:

[...]/node_modules/sequelize/lib/dialects/postgres/connection-manager.js:36
if (dataType.key.toLowerCase() === 'range') {
                         ^
    
TypeError: Cannot read property 'toLowerCase' of undefined