Persisting JSON with sequelize-typescript
Asked Answered
H

0

17

I want to store a simple JSON-Array in a MariaDB using sequelize-typescript. Here's a basic Model that would work in PostgreSQL, SQLite and MySQL.

class MyModel extends Model<MyModel> {
  @Column({
    type: DataType.JSON
  })
  options!: string[]
}

To get the same behaviour with MariaDB I tried four things:

1. Use @AfterFind or some other hook.

Problem: As stated in this issue in the github repo, there's a known bug that hooks will not fire on included models, so no chance

2. Implement an own custom JSON Data-Type (preferred solution)

Problem: Even copying the example in the sequelize-docs throws various typescript compiler issues and even If I use any types and trick the TS-compiler I don't know how to tell my other models that there is a new DataType.

3. Use a getter/setter for the same property

class MyModel extends Model<MyModel> {
  @Column({
    type: DataType.STRING
  })
  get options(): string[] {
    return JSON.parse(this.getDataValue('options'))
  }

  set options(value: string[]) {
    this.setDataValue('options', JSON.stringify(value))
  }
}

This throws compiler errors for the getDataValueand setDataValue methods:

Argument of type 'string' is not assignable to parameter of type 'this["options"]'
Type 'string' is not assignable to type 'string[]'

4. Use a getter/setter for a private property

What would work is to just store the Array as a string in the DB and use a getter/setter to access & parse this property.

class MyModel extends Model<MyModel> {
  @Column
  _options!: string;

  get options(): string[] {
    return JSON.parse(this._options)
  }

  set options(value: string[]) {
    this._options = JSON.stringify(value)
  }
}

As I said, that works, but I'd rather like to have something more generic that works faster for a larger number of fields, like a custom datatype.

So my question is:
Is there a convenient, short, easy, dynamic and reusable way to store JSON in a MariaDB?

Hydrogenous answered 10/12, 2019 at 22:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.