我想使用knex.raw()
方法创建一个枚举类型,这是我的migrate
代码:
import * as Knex from 'knex';
import { ChannelEnum } from '../types';
exports.up = function(knex: Knex): Promise<any> {
return Promise.all([
knex.schema
.createTable('channel', (t: Knex.TableBuilder) => {
t.increments();
const enumOptions: Knex.EnumOptions = {
useNative: true,
enumName: 'channel_nme_b'
};
t.enum('channel_nme_a', [ChannelEnum.FACEBOOK, ChannelEnum.GOOGLE, ChannelEnum.INSTAGRAM]);
t.enum('channel_nme_b', [ChannelEnum.FACEBOOK, ChannelEnum.GOOGLE, ChannelEnum.INSTAGRAM], enumOptions);
})
.then(() => {
return knex.raw(`create type "channel_nme_c" as enum (?,?,?);`, [
ChannelEnum.FACEBOOK,
ChannelEnum.GOOGLE,
ChannelEnum.INSTAGRAM
]);
})
.then(() => {
return knex.raw(`alter table "channel" add column if not exists channel_nme_c channel_nme_c;`);
})
]);
};
但是出现错误:
{ method: 'raw',
sql: 'create type "channel_nme_c" as enum (?,?,?);',
bindings: [ 'FACEBOOK', 'GOOGLE', 'INSTAGRAM' ],
options: {},
__knexQueryUid: 'f8fdf6f3-50d1-4b2e-afbc-8d9e971471fb' }
migration file "20181211102654_db.ts" failed
migration failed with error: create type "channel_nme_c" as enum ($1,$2,$3); - syntax error at or near "$1"
{ method: 'update',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ 0 ],
__knexQueryUid: '38a05697-3446-432a-a3f5-5d0ca7940049',
sql: 'update "knex_migrations_lock" set "is_locked" = ?',
returning: undefined }
error: syntax error at or near "$1"
at Connection.parseE (/Users/ldu020/workspace/nodejs-pg-knex-samples/node_modules/pg/lib/connection.js:554:11)
at Connection.parseMessage (/Users/ldu020/workspace/nodejs-pg-knex-samples/node_modules/pg/lib/connection.js:379:19)
at Socket.<anonymous> (/Users/ldu020/workspace/nodejs-pg-knex-samples/node_modules/pg/lib/connection.js:119:22)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at Socket.Readable.push (_stream_readable.js:208:10)
at TCP.onread (net.js:597:20)
似乎bindings
的raw错误,但不知道为什么。
答案 0 :(得分:0)
可能postgresql不允许将值绑定用于枚举值。您需要将这些值插入到SQL字符串中,例如:
return knex.raw(`create type "channel_nme_c" as enum ('${ChannelEnum.FACEBOOK}', '${ChannelEnum.GOOGLE}', '${ChannelEnum.INSTAGRAM}')`);
答案 1 :(得分:0)
我为使用pg
驱动程序创建枚举类型进行了更多测试。在这种情况下,pg
驱动程序似乎不支持值绑定。
const sql = `
create type "channel_nme_d" as enum ($1, $2, $3);
`;
const res = await client.query(sql, [ChannelEnum.FACEBOOK, ChannelEnum.GOOGLE, ChannelEnum.INSTAGRAM]);
以上代码将引发错误:error: syntax error at or near "$1"
下面的代码可以正常工作。
const sql = `
create type "channel_nme_e" as enum ('${ChannelEnum.FACEBOOK}','${ChannelEnum.GOOGLE}','${
ChannelEnum.INSTAGRAM
}');
`;
const res = await client.query(sql);
检查枚举类型:
nodejs-pg-knex-samples-# \dT
List of data types
Schema | Name | Description
--------+---------------+-------------
public | channel_nme_b |
public | channel_nme_c |
public | channel_nme_e |
(3 rows)
似乎knex.raw(sql, bindings)
只是直接将原始SQL和绑定传递给query
的{{1}}方法。