<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Richard Coates (he/him)</title>
    <description>The latest articles on DEV Community by Richard Coates (he/him) (@rscoates).</description>
    <link>https://dev.to/rscoates</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F290135%2F9d9514bf-7356-48d2-beae-9cfbb5aa038b.jpg</url>
      <title>DEV Community: Richard Coates (he/him)</title>
      <link>https://dev.to/rscoates</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rscoates"/>
    <language>en</language>
    <item>
      <title>How to insert a Postgres Array from a Stringified JSON Array</title>
      <dc:creator>Richard Coates (he/him)</dc:creator>
      <pubDate>Fri, 06 Mar 2020 16:13:33 +0000</pubDate>
      <link>https://dev.to/rscoates/how-to-insert-a-postgres-array-from-a-stringified-json-array-13n3</link>
      <guid>https://dev.to/rscoates/how-to-insert-a-postgres-array-from-a-stringified-json-array-13n3</guid>
      <description>&lt;p&gt;In an endpoint in a project that I’ve been working on this week, we receive a JSON payload from a call to our API, but the Postgresql database with which we’re working stores the contents of this payload as a Postgres Array. &lt;/p&gt;

&lt;p&gt;To make matters a little more complicated, the value field is sometimes a single string, rather than an array, and so the .sql file takes either a stringified JSON or a string as its argument.&lt;/p&gt;

&lt;p&gt;I couldn’t find a simple explanation for how to work with this particular arrangement, because I don't imagine it's that common. However, just in case it's useful for anyone else, here's how to do it (and hello me in the future, when I’ve forgotten how to do this!).&lt;/p&gt;

&lt;p&gt;Consider the following table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TYPE&lt;/span&gt; &lt;span class="n"&gt;v_type&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nb"&gt;ENUM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'text'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'list'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;demo_table&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;bigserial&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;value_type&lt;/span&gt; &lt;span class="n"&gt;v_type&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;text_value&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;list_value&lt;/span&gt; &lt;span class="n"&gt;_text&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we want to insert either a &lt;code&gt;text_value&lt;/code&gt; or a &lt;code&gt;list_value&lt;/code&gt; depending on the &lt;code&gt;value_type&lt;/code&gt; column.&lt;/p&gt;

&lt;p&gt;The insert statement must look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;    &lt;span class="k"&gt;INSERT&lt;/span&gt; 
    &lt;span class="k"&gt;INTO&lt;/span&gt;
        &lt;span class="n"&gt;demo_table&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="k"&gt;values&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="k"&gt;case&lt;/span&gt; 
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'text'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;   &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; 
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; 
        &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; 
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'list'&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;   &lt;span class="n"&gt;ARRAY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
                &lt;span class="n"&gt;json_array_elements_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; 
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; 
        &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason that the second part is so complicated is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Postgres functions are typesafe, and so each function needs to ensure that its inputs are of the correct type. Therefore, you need to specify that $2 will be a text getting cast to JSON, which can then be fed into json_array_elements_text (which will only accept a JSON). Note that this may error at runtime if the text isn’t a valid JSON structure (but that doesn't concern us - it will be processed beforehand).&lt;/li&gt;
&lt;li&gt;The only way in Postgres (that I could find) to turn a JSON into an array is to use json_array_elements to expand the JSON array to a set of text values, and then ARRAY to take the text values and make them into an array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Credit to Erwin Brandstetter for &lt;a href="https://dba.stackexchange.com/a/54289"&gt;this StackExchange answer&lt;/a&gt;, which provided the bulk of my research.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>json</category>
      <category>array</category>
    </item>
  </channel>
</rss>
