2

I'm trying to insert a ruby hash into Postgres JSON column. Basically its a collection of hash in an array. So you have a structure something like:

[{"a":"1"},{"b":"2"},{"c":"3"}] #the length goes on

The existing code for whatever I'm trying to do is:

require 'pg'

freq = 0.05
$test = 0
$sinval = 0
arr = Array.new

@conn = PG.connect(
        :dbname => 'test_db',
        :user => 'abc',
        :port => 6100,
        :host => 'localhost'
        )

while true do
        $test = ($test+freq).round(2)
        $sinval = Math.sin($test*(Math::PI/180)).round(6)
        hash = {:value=>$sinval.to_s}
        arr.push(hash.to_json)
        if(arr.length>=1800)
                @conn.exec("INSERT INTO sinewave(data) VALUES('#{arr}');")
                arr = Array.new
        end
end

But now, I'm not being able to store it in the database the way I want. For each row, what I'd like to see is a JSON Array of 1800 objects and the structure be:

[{"a":"1"},{"b":"2"},{"c":"3"}]

I don't know whats wrong. May be hash = {:value=>$sinval.to_s} this line is incorrect. Other ways to sort this out?

9
  • what error do you get? Commented Oct 26, 2016 at 6:24
  • I didn't receive any error! everything executes fine. however, the data stored in the database is something of form "["{\"value\":\"-0.000873\"}", "{\"value\":\"-0.001745\"}", "{\"value\":\"-0.002618\"}", "{\"value\":\"-0.003491\"}", "{\"value\":\"-0.004363\"}", "{\"value\":\"-0.005236\"}", "{\"value\":\"-0.006109\"}", "{\"value\":\"-0.006981\"}"] Commented Oct 26, 2016 at 6:25
  • can anybody tell me how do you use html_safe from rails in ruby? Commented Oct 26, 2016 at 6:26
  • 1
    are you trying to create a single row with all the values? that kinds of defeats the purpose of using a database Commented Oct 26, 2016 at 6:27
  • Isn't this what you want? can you just use JSON.parse to parse the record and retrieve the original form? Commented Oct 26, 2016 at 6:27

2 Answers 2

3

Postgres persists JSON type as a JSON string. This is a string that you can get by calling #to_json on most objects in ruby. Here's a link to how postgres deal with JSON type in more details.

https://www.postgresql.org/docs/9.6/static/datatype-json.html

Because it's persisted as a JSON string, all the quotes will be escaped. That's why something like this

{ a: 1 }

will become this

"{\"a\":1}"

The \ is for escaping the quote so that it does not end the string.

When you retrieve it from postgres (I personally never used JSON type in PG but I believe it works similarly as JSON.parse on this string), you won't see the slashes any more. And the above process is done by postgres.

Sign up to request clarification or add additional context in comments.

1 Comment

storing things with a escape quote in the database doesn't seem like a good practice. Thank you though :) cheers!
2

If you convert hash object into JSON in ruby, it adds escape character automatically so try converting the whole array of object into JSON instead of hash object.

require 'pg'

freq = 0.05
$test = 0
$sinval = 0
arr = Array.new

@conn = PG.connect(
        :dbname => 'test_db',
        :user => 'abc',
        :port => 6100,
        :host => 'localhost'
        )

while true do
        $test = ($test+freq).round(2)
        $sinval = Math.sin($test*(Math::PI/180)).round(6)
        hash = {:value=>$sinval.to_s}
        arr.push(hash)
        if(arr.length>=1800)
                @conn.exec("INSERT INTO sinewave(data) VALUES('#{arr.to_json}');")
                arr = Array.new
        end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.