node-postgres icon indicating copy to clipboard operation
node-postgres copied to clipboard

Error inserting array into PostgreSQL column: Malformed array literal

Open belwalshubham opened this issue 1 year ago • 2 comments

I am using objection.js in my application.
I'm encountering an issue while trying to insert an array of strings into a PostgreSQL database column. The column is defined as follows:

path TEXT[] NOT NULL

here is the schema:

path: { type: 'array', items: { type: 'string' }, notNull: true }

here I send the format of path like this

await updateGlobalChatNotificationOptIn({
      variables: {
        path: ['chat'],
        option: updatedGlobalChatNotificationOptIn,
      },

updateNotificationOption(path: [String!]!, option: String!): NotificationUserOption

when I pass the path something like this ['chat']

  Mutation: {
    updateNotificationOption: async (_, { path, option }, ctx) => {
      if (!ctx.user)
        throw new Error(
          'Cannot updateNotificationOption for an unregistered user',
        )
      if (!['off', 'inherit', '30MinSummary'].includes(option))
        throw new Error(
          `Unrecognized option '${option}' passed to updateNotificationOption`,
        )

      const groupId = ctx.req.headers['group-id']
      const userId = ctx.user

      // Find the existing record based on userId, path, and groupId
      const existingOption = await NotificationUserOption.query().findOne({
        userId,
        path,
        groupId,
      })

      if (existingOption) {
        // Update the 'option' field of the existing record
        return NotificationUserOption.query().patchAndFetchById(
          existingOption.id,
          { option },
        )
      }

      // If no existing record, create a new one
      return NotificationUserOption.query().upsertGraphAndFetch(
        { userId, path, groupId, option },
        { insertMissing: true },
      )
    },
    
  extend type Mutation {
    updateNotificationOption(path: [String!]!, option: String!): NotificationUserOption
  }

However, when I try to insert the array using this code, I encounter the following error:

malformed array literal: "["chat"]" "[" must introduce explicitly-specified array dimensions.

I've tried using single brackets ('{chat}') and double brackets ([['chat']]), but neither seems to work.

How can I correctly format the array literal so that I can insert the array into the PostgreSQL column without encountering this error?

belwalshubham avatar Aug 06 '23 03:08 belwalshubham

Objection.js probably forces arrays to be JSON-encoded so people can use them at the top level with json/jsonb columns.

charmander avatar Aug 06 '23 21:08 charmander

did you find a solution to this?

daniserafs avatar Jan 04 '24 19:01 daniserafs

I ran into this same "malformed array literal" error while trying to insert into my string array column using something like ['one', 'two'].

I found https://github.com/Vincit/objection.js/issues/52 which has a comment that mentions Objection maps all object and array properties into strings by default to support the common json/jsonb column types (as predicted above). It says when using an array column type, you'll need to override the jsonAttributes function in the model.

My table model includes a jsonb column (foo) and a varchar(255)[] column (bar) so I added the jsonb column name to this jsonAttributes array

static get jsonAttributes() {
  return ['foo'];
}

and I was finally able to insert ['one', 'two'] into my string array column (bar) and continue to write to the jsonb column.

jordanweiler avatar Mar 14 '24 22:03 jordanweiler