New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Field with type Sequelize.JSON returns string when MySQL dialect is used for a MariaDB database #10946
Comments
Also, I found this test in your repo https://github.com/sequelize/sequelize/blob/master/test/integration/model/json.test.js#L771, where you get the JS object using And in your code here https://github.com/sequelize/sequelize/blob/master/lib/data-types.js#L514, I couldn't find anywhere, where do you parse the JSON string into an object. |
I wonder - if about the idea - does that types only for writing? or should work for read also? Is there a documentation about inner interfaces (Like abstract type and so on)? |
@sushantdhiman any feedback on this? |
It should JSON.parse it like for example mariadb dialect does. |
@misos1 can you provide a link to a code which does this? |
Check |
http://docs.sequelizejs.com/manual/dialects.html#mariadb const sequelize = new Sequelize('database', 'username', 'password', {
dialect: 'mariadb', // <--- this is the key (mysql doesn't contain .parse
dialectOptions: {connectTimeout: 1000} // mariadb connector option
}) |
@vvscode Looks like it's a V5 feature, because on V4 I'm getting this: |
Just asking, is you table created by sequelize? Cause I don't see a call to David |
@ddolcimascolo Your tables were probably not created by sequelize v4 nor v5 and I doubt that older version of sequelize created JSON columns. Sequelize will for some reason create mysql LONGTEXT type in db when you use Sequelize.JSON. If you already have mysql JSON column in db then I do not doubt it is working because seems mysql2 connector supports JSON columns and I saw calls to JSON.parse in sources so it will directly return JS object to sequelize and sequelize in this case does not must parse string. |
You got me puzzled... All my Mysql tables are created through migration scripts (applied with https://github.com/sequelize/umzug) using sequelize query interface, here's one for your reference: 'use strict';
module.exports = {
up: (qi, DataTypes) => qi.createTable('items', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
payload: DataTypes.JSON
})),
down: qi => qi.dropTable('items')
};
The resulting table indeed has a |
Ok seems this problem is here only when using mysql dialect with mariadb database, not with mysql database. |
OK, thus the new This issue can probably be closed then, if everyone agrees. |
This is not so simple. Mariadb dialect is still new and has bugs which prevents to use it as direct replacement in already existing projects based on mysql dialect. It was added in sequelize v5. This bug should be easy to fix. Sequelize or mysql dialect could detect that it got string instead of JS object and simply parse it. https://github.com/sequelize/sequelize/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+mariadb |
Yeah, I got your point but on the other hand I believe MariaDB wasn't supported on v4 (or was it?) |
Yes it was and even in sequelize v3 and probably in even older versions. Through mysql dialect. https://sequelize.readthedocs.io/en/v3/ |
Hi @ddolcimascolo, @misos1 agree, I also found docs on JSON support in older versions of Sequelize.
@ddolcimascolo, does this mean we are going to fallback again to getter/setter for JSON types, or we can expect some fix on at least Sequelize v4? What do you think? |
Hi sorry for the late reply. Is there anything preventing you from upgrading to v5 where MariaDB is officially supported? David |
Hey, |
I will close the issue, but if anyone still has problems feel free to ping me. |
@papb But as I wrote mysql dialect is still superior to new mariadb dialect even when using with mariadb database. So it has sense to fix this little bug. Just convert that string into js object so mysql dialect will behave in same way for mariadb database as for mysql database. |
@misos1 Ah, I didn't know that. So MySQL dialect + MariaDB database yields a string instead of an object... Can you please clarify:
|
|
@misos1 Very interesting. Also, just for my information, can you list a few reasons for what you said:
I'm asking because I am not familiar with those dialects... I would never expect this if you asked me. |
@papb Why you think it should not work? This is not like using postgresql database with mysql dialect.
If it would not work then why was used mysql dialect for mariadb database before sequelize v5? Using directly mariadb dialect with mariadb driver with mariadb database can have some advantages. I saw somewhere this combination should be faster but still as mariadb database is supposed to be drop-in replacement for mysql then it should and it is working also with mysql2 driver and mysql dialect. Unfortunately mariadb dialect does not feels mature enough (I do not mean mariadb driver but sequelize side).
There are for example these (and probably more): More which also seems specific to mariadb dialect: |
@misos1 Thanks for the detailed explanation! I am convinced. |
Looks the issue is only partially fixed in Where you read records from Here is a code snippet:
See a working demo here: https://github.com/omegascorp/sequelize-mariadb-json-test |
Hey, sorry to revive this, but do we got any progress on this matter? When I try to update a model that has a JSON field, the field is still empty after I save it, even though I got no errors. The process goes on smoothly. |
@omegascorp I have the same problem when including some model, JSON fields convert to strings thas so bad. |
Sorry, I didn't update ya guys. |
@papb I see you re-opened this issue in August 2019. Is there any expectation that a future release of Sequelize will seamlessly provide the required Also, if there is a suggested method to patch / workaround the issue by adding code into the model or into an event handler that would be very much appreciated. Thanks! |
@medington Apparently there is no alternative yet |
This issue has been automatically marked as stale because it has been open for 14 days without activity. It will be closed if no further activity occurs within the next 14 days. If this is still an issue, just leave a comment or remove the "stale" label. 🙂 |
Is there anything new on this issue? I'm also stuck with the same problem. |
Struggling with the same here. One workaround would be to create getters and setters, but they will not trigger if the object is a nested child of a find() with associations. |
Same problem |
Still a problem. I am using MySQL database with MySQL dialect. I also use sqluelize-typescript: import { Role } from './Role'
import { BelongsTo, Column, CreatedAt, DataType, Model, PrimaryKey, Table, UpdatedAt } from 'sequelize-typescript'
@Table({tableName: 'role_permission'})
export class RolePermission extends Model {
@PrimaryKey
@Column({type: DataType.UUID, defaultValue: DataType.UUIDV4})
declare id: string
@Column
permission: string
@Column({
type: DataType.JSON,
defaultValue: [],
})
scopes: string[]
@CreatedAt
created_at: Date
@UpdatedAt
updated_at: Date
@BelongsTo(() => Role, {foreignKey: 'role_id'})
role: Role
} I had to do this instead: @Column({
type: DataType.TEXT,
defaultValue: [],
get: function(this: RolePermission) {
return JSON.parse(this.getDataValue('scopes') as unknown as string)
}
})
scopes: string[] Edit
But now I get |
In my case, I used MySql DB on the MariaDB driver!
also you need to install mariadb package it worked for me. |
Either there are still some problems here or I am doing something completely incorrect. I am using Sequelize 6.37.0. I have a column in a database table named When I create a new row, the row is created successfully and the JSON object is stored correctly. However, if I update the row with the same data, the object is then stringified. For example, it is going from Scenario 1:
Row Creation: OK Scenario 2: Let’s try to fix the Row Get from returning a string to instead, returning an object.
Row Creation: Fails - uncaughtException: \“[object Object]\” is not valid JSON Scenario 3: Remove the get and try to fix the update row from storing a stringified object
Row Creation: Fails - SyntaxError: \“[object Object]\” is not valid JSON Scenario 4: Change DataType to TEXT
Row Creation: Fails - SequelizeValidationError: string violation: extra cannot be an array or an object Basically what I am after is when I create a new row, the The following works to create, update and get however, because the type is
Query
Error
If I change the data type to JSON, the query and where clause work fine however now the data in the extra column is stringified again. Any help is greatly appreciated. |
What are you doing?
When querying a model, which has a field with type
sequelize.JSON
, it returns JSON string instead of parsed JS object for that field.To Reproduce
Steps to reproduce the behavior:
Test
, which has two fields:id
anddata
. The latter one is of typesequelize.JSON
.Test
model, providing JS object fordata
field. On the next line when I print type ofdata
, it prints correctlyobject
.findOne
(no difference how you query), the returned object'sdata
field isstring
now.What do you expect to happen?
I expect to get a parsed JS object out of my JSON field.
What is actually happening?
I'm getting JSON string instead of object.
Environment
Dialect:
Dialect library version: mysql2 - 1.6.4
Database version: mysql Ver 15.1 Distrib 10.3.14-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2 (The DB is run in Docker using official MariaDB image)
Sequelize version: 4.41.2
Node Version: v10.15.2
OS: macOS Mojave, 10.14.3 (18D109)
Tested with latest release:
The text was updated successfully, but these errors were encountered: