0

I want to get a JSON object from the Google Direction API. The Google API response is formatted JSON with newlines like this:

{
  geocoded_waypoints: [
    {
      geocoder_status: "OK",
      place_id: "ChIJpws0Ra-DnkcRHLPUqU7qpiM",
      types: [
        "route"
      ]
    }
  ]
}

But I need the response in one single line, without formatting.

Can I do this with curl? I downloaded the newest version.

I try this yet:

  1. this version put each line in a row in the database

    COPY "routing_import_gm" ("request") FROM PROGRAM 'curl "https://maps.googleapis.com/maps/api/directions/json?origin=48.xxxxxx,+11.yyyyyy&destination=48.xxxxxx,+11.yyyyyyy&key=***"';
    
  2. cause erros:

    COPY "routing_import_gm" ("request") FROM PROGRAM 'curl "https://maps.googleapis.com/maps/api/directions/json?origin=48.xxxxxx,+11.yyyyyy&destination=48.xxxxxx,+11.yyyyyyy&key=***" | tr -d ''\n'' ';
    
Tomalak
  • 332,285
  • 67
  • 532
  • 628
Tibor
  • 159
  • 6
  • What operating system are you using? Show the line of code that does the API call. – Tomalak Nov 20 '21 at 10:09
  • windows10 64bit, my problem is. i want to get the response and copy it with copy from program in a postgresql database field json, but i get always sql-error because the answer is not well formed withot new lines etc. – Tibor Nov 20 '21 at 10:30
  • Ah! The newlines in the JSON response are not your issue. The way you do your database insert is. Post the code that does that, we will figure out a better way. – Tomalak Nov 20 '21 at 15:14
  • i posted the code in the question, i tried so far – Tibor Nov 20 '21 at 21:15
  • I see you're doing this from within Postgres. I thought you'd be running a batch file or so to load data. In this case... you could use PowerShell instead of curl for Windows. See my answer. – Tomalak Nov 21 '21 at 07:44

1 Answers1

1

The following PowerShell command loads JSON data in any format from a given URL and outputs a single line of JSON as its result:

Invoke-RestMethod "https://your/url" | ConvertTo-Json -Compress -Depth 10
  • Invoke-RestMethod expects a JSON response, and decodes it into a data structure.
  • ConvertTo-Json takes a data structure and turns it into JSON.
    • -Compress skips all indentation and all newlines,
    • -Depth sets the maximum nesting level (which is only 2 by default, not enough for your data).

You can run PowerShell with an in-line command like this:

powershell -NoLogo -NonInteractive -Command "..."

And you could use that in your COPY statement.

COPY "routing_import_gm" ("request")
FROM PROGRAM 'powershell -NoLogo -NonInteractive -Command "Invoke-RestMethod "https://your/url" | ConvertTo-Json -Compress -Depth 10"';

You say you have trouble with Unicode characters. That is a rather tricky problem in this setup. There are two issues:

  • It requires proper configuration in multiple places to get Unicode characters across for shell commands. It's technically possible, but setting this up is a major pain.
  • JSON offers an ASCII-compatible format, which encodes all Unicode characters as \u..... That would side-step the issue, but ConvertTo-JSON in PowerShell 5.1 (which you have) does not offer that natively. The -EscapeHandling parameter (which does that) requires PowerShell 6.2.

We rely on ConvertTo-JSON to format the incoming JSON as a single line, and we can't simply change your PowerShell version. A possible way out would be to replace all non-ASCII characters with \u.... character codes using regex:

[regex]::Replace($json, '[^\x00-\x7f]', {param($m) '\u{0:X4}'-f[int][char]$m[0].value})

If $json is '{"test": "Smørrebrød "}', the above returns '{"test": "Sm\u00F8rrebr\u00F8d \uD83E\uDD6A"}', which is both valid JSON and ASCII-only, so it won't give you any trouble with COPY FROM PROGRAM.

Applied to the code above, we would end up with this:

powershell -NoLogo -Command "$json = Invoke-RestMethod 'https://your/url' | ConvertTo-Json -Compress -Depth 10; [regex]::Replace($json, '[^\x00-\x7f]', {param($m) '\u{0:X4}'-f[int][char]$m[0].value})"

Notes

  • While all of this is pretty convoluted, the advantage of using PowerShell is
    • All of it (requesting the URL, getting the JSON from the response, converting it) is Unicode-aware and never crosses process boundaries, as e.g. piping from curl for Windows into jq or sed or tr for Windows would. Crossing process boundaries always has a chance of mangling your Unicode data.
    • If the server itself returns literal Unicode characters in the JSON, they would get converted to \u.... as well.
    • PowerShell is readily available on every Windows machine, other tools must be installed first.
  • If you can upgrade your PowerShell version, you could drop the regex part and use ConvertTo-JSON -EscapeHandling EscapeNonAscii instead.
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • in the url i must use &. powershell -NoLogo -NonInteractive -Command "Invoke-RestMethod 'https://maps.googleapis.com/maps/api/directions/json?origin=48.**,+11.**"&"destination=48.**,+11.**"&"key=**' | ConvertTo-Json -Compress -Depth 10" - but the syntax is not correct... – Tibor Nov 23 '21 at 07:04
  • @Tibor You should be able to debug syntax errors yourself. I can see that you have double quotes around the `&`. Don't do that. Also you have single quotes around the URL itself, I've used double quotes for a reason. – Tomalak Nov 23 '21 at 07:39
  • 1
    now works...powershell -NoLogo -NonInteractive -NoProfile -Command "Invoke-RestMethod 'https://maps.googleapis.com/maps/api/directions/json?origin=48.xxxx,+11.xxxxx&destination=48.xxxxxx,+11.xxxxxx&key=xxxxxxxxx' | ConvertTo-Json -Compress -Depth 10" – Tibor Nov 23 '21 at 13:00
  • @Tibor That's good to hear! (Don't forget to tick the answer as accepted if it solved your issue.) – Tomalak Nov 23 '21 at 14:54
  • but it works only in powershell, my postgres db has the problem with »UTF8«: 0xb8. DB hast UTF8, OS is win – Tibor Nov 23 '21 at 15:00
  • @Tibor Sigh... That's too bad. What's your PowerShell version (`Write-Host $PSVersionTable.PSVersion.ToString()`) – Tomalak Nov 23 '21 at 15:12
  • here is my version: 5.1.19041.1320 – Tibor Nov 23 '21 at 15:15
  • @Tibor Oh well... This is getting a lot more complicated than I had hoped. See updated answer. It's becoming one of those "it's not stupid if it works" kinds of things, but I think it would work. – Tomalak Nov 24 '21 at 08:58
  • thx and sorry for the late answer. now i intalled pwsh 7. ConvertTo-JSON -EscapeHandling EscapeNonAscii is works from the command line. And it works if i copy manuelly and to put in my database with the insert values method. But over COPY "routing_import_gm" ("request") FROM program 'pwsh -NoLogo -NonInteractive -Command "Invoke-RestMethod ''https://maps.google....&.....'' | ConvertTo-JSON -Compress -Depth 10 -EscapeHandling EscapeNonAscii"'; i get SQL Faulire [38000] Kind Prozess ended with Code 1 – Tibor Nov 29 '21 at 18:21