The previous answers are outdated by almost a decade. Python 3.6+ has slightly easier methods of doing this (in my opinion, subprocess.run() is a bit cleaner because you don't have to resort to Popen hacking).
Here's a Python 3.9 function that will let you (1) log into SQL*Plus, (2) execute a SQL script, and (3) parameterize arguments to it:
def execute_sql_script_via_sqlplus():
sqlplus_login_command = 'sudo sqlplus oracle_user/oracle_password'
sql_script_path = '/example/path/to/some_script.sql'
sql_script_arguments = ["foo", "bar"]
sql_command = "@" + str(sql_script_path)
for argument in sql_script_arguments:
sql_command += f" {argument}"
result = subprocess.run(
sqlplus_login_command,
input=sql_command,
shell=True,
text=True,
capture_output=True
)
return result.stdout, result.stderr
I'll break this down a little:
subprocess.run(sqlplus_login_command) represents whatever command you'd use to log into SQL*PLUS. It doesn't necessarily have to use -S connection_string - especially if you have a valid local TNS configuration. This happens before we try to execute any SQL scripts.
sql_command is an absolute system path to the script, which is prepended with @, and suffixed with a string-delimited list of arguments. These arguments are referenced within the script via "&1", "&2", etc. Arguments are not zero-indexed.
input=sql_command fires off the actual SQL script after the initial SQL*Plus login.
capture_output allows you to capture the stdout/stderr.
text=True is necessary to make input=sqlcommand work.
- See Actual meaning of 'shell=True' in subprocess for details on
shell=True.