Python SQL*Plus subprocess Error: sgslunUDPNew: Unable to create communication endpoint
Python SQL*Plus subprocess Error: sgslunUDPNew: Unable to create communication endpoint
所以我们使用 python 和 sqlplus 将所有表导出到 csv 文件。由于我们的 oracle 数据库中有一些 unicode 数据,我们需要将 NLS_LANG
环境变量设置为 .AL32UTF8
,以便 sqlplus 在假脱机到 csv
文件时实际使用 utf-8 编码。
手动执行此操作并在 cmd 中设置 NLS_LANG
变量工作正常。
但是下面的 python 片段:
...
print("Connecting to database ...")
with subprocess.Popen(["C.\My\Path\To\sqlplus.exe", "MyUser/MyPassword@whocares.com:1522/MyDataBase"], stdin=subprocess.PIPE, encoding='utf-8', env={"NLS_LANG": ".AL32UTF8"}) as p:
p.stdin.write("set echo off newpage 0 pagesize 0 linesize 3000 feed off head off trimspool on \n")
p.stdin.flush()
...
导致 sqlplus 失败并出现此错误:
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Oct 16 15:24:37 2020
Version 19.8.0.0.0
Copyright (c) 1982, 2020, Oracle. All rights reserved.
sgslunUDPNew: Unable to create communication endpoint
ERROR:
ORA-12154: TNS:could not resolve the connect identifier specified
打开子进程时省略环境变量但效果很好:
...
print("Connecting to database ...")
with subprocess.Popen(["C.\My\Path\To\sqlplus.exe", "MyUser/MyPassword@whocares.com:1522/MyDataBase"], stdin=subprocess.PIPE, encoding='utf-8') as p:
p.stdin.write("set echo off newpage 0 pagesize 0 linesize 3000 feed off head off trimspool on \n")
p.stdin.flush()
...
更有趣的是,我们设置哪个环境变量并不重要。但是,一旦我们将 any 环境变量传递给 python 中的 sqlplus 子进程,它就会崩溃。
我们不确定这是否与 python 或 sqlplus 或两者的组合有关,我们将不胜感激任何帮助。
就版本而言,我们使用 Windows 10
与 SQL*Plus: Release 19.0.0.0.0 - Production Version 19.8.0.0.0
和 Python 3.8.5
sgslunUDPNew:无法创建通信端点
错误:
ORA-12154:
意味着 Oracle 网络层 (TNS) 尝试打开无效或禁止的端口使用 OS 网络库 - 这可能是包含端口的格式错误或错误编码字符串的结果 - 最后 TNS 报告错误传递给 SQL*Plus
所以 - 由于 SQLPLUS 可以启动,这为测试提供了机会
with subprocess.Popen(["C.\My\Path\To\sqlplus.exe << EOF connect MyUser/MyPassword@whocares.com:1522/MyDataBase EOF ",["" ], stdin=subprocess.PIPE, encoding='utf-8', env={"NLS_LANG": ".AL32UTF8"}) 作为 p:
请查看您使用 Unicode 时遇到的“不错”结果 - 那是我一周前发现的。最后我相信 SQL*Plus 可能无法在内部正确解码 unicode。将测试这些东西。
How to connect to database using QOCI or QODBC with correct encoding?
无论如何 - 为了获得通用性,考虑将 pyODBC 与 Oracle ODBC 驱动程序一起使用,它得到了官方支持 - 或者其他数据库的其他 ODBC
好的 - 稍微测试一下并让它工作
import subprocess, os
line = "SCOTT/tiger@xxx.xxx.xxx.xxx:yyyyy/sssss"
# fails
# subprocess.run(["sqlplus.exe", line], env={"NLS_LANG": ".AL32UTF8"})
my_env = os.environ.copy()
my_env["NLS_LANG"] = ".AL32UTF8"
# works
# subprocess.run(["sqlplus.exe", line], env=my_env)
#adopting solution
print("Connecting to database ...")
with subprocess.Popen(["C:\ORACLE\IC\12201\instantclient_12_2\sqlplus.exe", "SCOTT/tiger@xxx.xxx.xxx.xxx:yyyyy/sssss"], stdin=subprocess.PIPE, encoding='utf-8', env=my_env) as p:
p.stdin.write("set echo off newpage 0 pagesize 0 linesize 3000 feed off head off trimspool on \n")
p.stdin.flush()
输出
Connecting to database ...
SQL*Plus: Release 12.2.0.1.0 Production on Sun Oct 18 00:07:22 2020
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Last Successful login time: Sun Oct 18 2020 00:04:57 +02:00
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options
SQL> SQL> Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options
最终使用 NLS_LANG 没有问题,因为即使是
subprocess.run(["sqlplus.exe", line], env={"A": "1"})
失败 - 你只需要创建一个像
这样的有效环境
my_env = os.environ.copy()
my_env["NLS_LANG"] = ".AL32UTF8"
并将其分配给喜欢的“env”
with subprocess.Popen( ..... , env=my_env)
弗兰克
所以我们使用 python 和 sqlplus 将所有表导出到 csv 文件。由于我们的 oracle 数据库中有一些 unicode 数据,我们需要将 NLS_LANG
环境变量设置为 .AL32UTF8
,以便 sqlplus 在假脱机到 csv
文件时实际使用 utf-8 编码。
手动执行此操作并在 cmd 中设置 NLS_LANG
变量工作正常。
但是下面的 python 片段:
...
print("Connecting to database ...")
with subprocess.Popen(["C.\My\Path\To\sqlplus.exe", "MyUser/MyPassword@whocares.com:1522/MyDataBase"], stdin=subprocess.PIPE, encoding='utf-8', env={"NLS_LANG": ".AL32UTF8"}) as p:
p.stdin.write("set echo off newpage 0 pagesize 0 linesize 3000 feed off head off trimspool on \n")
p.stdin.flush()
...
导致 sqlplus 失败并出现此错误:
SQL*Plus: Release 19.0.0.0.0 - Production on Fri Oct 16 15:24:37 2020
Version 19.8.0.0.0
Copyright (c) 1982, 2020, Oracle. All rights reserved.
sgslunUDPNew: Unable to create communication endpoint
ERROR:
ORA-12154: TNS:could not resolve the connect identifier specified
打开子进程时省略环境变量但效果很好:
...
print("Connecting to database ...")
with subprocess.Popen(["C.\My\Path\To\sqlplus.exe", "MyUser/MyPassword@whocares.com:1522/MyDataBase"], stdin=subprocess.PIPE, encoding='utf-8') as p:
p.stdin.write("set echo off newpage 0 pagesize 0 linesize 3000 feed off head off trimspool on \n")
p.stdin.flush()
...
更有趣的是,我们设置哪个环境变量并不重要。但是,一旦我们将 any 环境变量传递给 python 中的 sqlplus 子进程,它就会崩溃。
我们不确定这是否与 python 或 sqlplus 或两者的组合有关,我们将不胜感激任何帮助。
就版本而言,我们使用 Windows 10
与 SQL*Plus: Release 19.0.0.0.0 - Production Version 19.8.0.0.0
和 Python 3.8.5
sgslunUDPNew:无法创建通信端点 错误: ORA-12154: 意味着 Oracle 网络层 (TNS) 尝试打开无效或禁止的端口使用 OS 网络库 - 这可能是包含端口的格式错误或错误编码字符串的结果 - 最后 TNS 报告错误传递给 SQL*Plus
所以 - 由于 SQLPLUS 可以启动,这为测试提供了机会
with subprocess.Popen(["C.\My\Path\To\sqlplus.exe << EOF connect MyUser/MyPassword@whocares.com:1522/MyDataBase EOF ",["" ], stdin=subprocess.PIPE, encoding='utf-8', env={"NLS_LANG": ".AL32UTF8"}) 作为 p:
请查看您使用 Unicode 时遇到的“不错”结果 - 那是我一周前发现的。最后我相信 SQL*Plus 可能无法在内部正确解码 unicode。将测试这些东西。
How to connect to database using QOCI or QODBC with correct encoding?
无论如何 - 为了获得通用性,考虑将 pyODBC 与 Oracle ODBC 驱动程序一起使用,它得到了官方支持 - 或者其他数据库的其他 ODBC
好的 - 稍微测试一下并让它工作
import subprocess, os
line = "SCOTT/tiger@xxx.xxx.xxx.xxx:yyyyy/sssss"
# fails
# subprocess.run(["sqlplus.exe", line], env={"NLS_LANG": ".AL32UTF8"})
my_env = os.environ.copy()
my_env["NLS_LANG"] = ".AL32UTF8"
# works
# subprocess.run(["sqlplus.exe", line], env=my_env)
#adopting solution
print("Connecting to database ...")
with subprocess.Popen(["C:\ORACLE\IC\12201\instantclient_12_2\sqlplus.exe", "SCOTT/tiger@xxx.xxx.xxx.xxx:yyyyy/sssss"], stdin=subprocess.PIPE, encoding='utf-8', env=my_env) as p:
p.stdin.write("set echo off newpage 0 pagesize 0 linesize 3000 feed off head off trimspool on \n")
p.stdin.flush()
输出
Connecting to database ...
SQL*Plus: Release 12.2.0.1.0 Production on Sun Oct 18 00:07:22 2020
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Last Successful login time: Sun Oct 18 2020 00:04:57 +02:00
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options
SQL> SQL> Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Advanced Analytics
and Real Application Testing options
最终使用 NLS_LANG 没有问题,因为即使是
subprocess.run(["sqlplus.exe", line], env={"A": "1"})
失败 - 你只需要创建一个像
这样的有效环境my_env = os.environ.copy()
my_env["NLS_LANG"] = ".AL32UTF8"
并将其分配给喜欢的“env”
with subprocess.Popen( ..... , env=my_env)
弗兰克