0

Issue

I have this command, which works in the shell:

<ABS_PATH>/odbc2parquet query --connection-string "Driver={<DRIVER_NAME>};SERVER=<SERVER_IP>,<SERVER_PORT>;DATABASE=<DB_NAME>;UID=<UID>;PWD=<PWD>" <OUTPUT_PATH> "<QUERY>"

But the following python code doesn't work:

import subprocess
from typing import List

cmd_odbc: List[str] = [
    "<ABS_PATH>/odbc2parquet",
    "query",
    "--connection-string",
    '"Driver={<DRIVER_NAME>};SERVER=<SERVER_IP>,<SERVER_PORT>;DATABASE=<DB_NAME>;UID=<UID>;PWD=<PWD>"',
    "<OUTPUT_PATH>",
    '"<QUERY>"'
]
process_odbc: subprocess.Popen = subprocess.Popen(cmd_odbc)
process_odbc.wait()

This raises the following error:

Error: ODBC emitted an error calling 'SQLDriverConnect':
State: IM002, Native error: 0, Message: [unixODBC][Driver Manager]Data source name not found and no default driver specified

Instead, I have to do the following workaround

import subprocess
from typing import List

cmd_odbc: List[str] = [
    "<ABS_PATH>/odbc2parquet",
    "query",
    "--connection-string",
    '"Driver={<DRIVER_NAME>};SERVER=<SERVER_IP>,<SERVER_PORT>;DATABASE=<DB_NAME>;UID=<UID>;PWD=<PWD>"',
    "<OUTPUT_PATH>",
    '"<QUERY>"'
]
process_odbc: subprocess.Popen = subprocess.Popen(" ".join(cmd_odbc), shell=True)
process_odbc.wait()

Question

Why doesn't the first code work while the second does? What is the main difference here?

Thanks to everyone reading.

GregoirePelegrin
  • 1,206
  • 2
  • 7
  • 23
  • 3
    Those double-quotes around two of the parameters in the shell version aren't actually being passed on to the command; they're just ensuring that the contents get passed as a single parameter, even if they contain spaces or other characters that are meaningful to the shell. You shouldn't have them in your Python code - having them as separate items in the list is all you need to do to make them unambiguous. – jasonharper Jan 16 '23 at 16:13
  • In `shell=True` those inner quotes can be necessary, but with `shell=True` you're completely defeating the benefits and purpose of using a list in the first place. Take out the quotes, and stick to the default `shell=False`. – Charles Duffy Jan 16 '23 at 17:51

0 Answers0