pyspark Oracle侦听器连接错误:oracle.net.ns.NetException:ORA-12541:无法连接,主机www.example.com端口1521上没有侦听程序127.0.0.1

zpjtge22  于 12个月前  发布在  Spark
关注(0)|答案(1)|浏览(109)

我正在使用Python 3.11.5在Docker中创建一个PySpark 3.4.1应用程序,它应该能够通过JDBC连接连接到多种类型的数据库。我正在测试与本地Oracle DB的连接,我在另一个容器中使用docker设置了这个连接。但是,我得到以下错误:

Py4JJavaError: An error occurred while calling o316.load.
: java.sql.SQLException: ORA-12541: Cannot connect. No listener at host 127.0.0.1 port 1521. (CONNECTION_ID=ZHRvV1iVRICqrdGeoIq7BQ==)

当我运行时(使用jar:“ojdbc11.jar”):

connection_opts = {
    "driver": "oracle.jdbc.driver.OracleDriver",
    "url": "jdbc:oracle:thin:@127.0.0.1:1521/FREEPDB1",
    "dbtable": "select * from xtable",
    "user": "my_db_admin",
    "password": "20pwd23",
}
df = spark.read.format("jdbc").options(**connection_opts).load()

docker-compose.yml文件如下:

version: "3.3"
services:
  spark-master:
    image: my_pyspark_image:latest
    tty: true
    stdin_open: true
    ports:
      - "9090:8080"
      - "7077:7077"
  oracle-localdb:
    # Creation reference: https://hub.docker.com/r/gvenzl/oracle-free
    image: gvenzl/oracle-free:slim
    shm_size: 1g
    ports:
      - '1521:1521'
    environment:
      ORACLE_RANDOM_PASSWORD: true
      APP_USER: my_db_admin
      APP_USER_PASSWORD: 20pwd23
    volumes:
      - type: volume
        source: pyspark_oracle-volume
        target: /opt/oracle/oradata
volumes:
  pyspark_oracle-volume:
    # external: true

运行lsnrctl status时:

LSNRCTL for Linux: Version 23.0.0.0.0 - Developer-Release on 09-SEP-2023 18:49:38

Copyright (c) 1991, 2023, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC_FOR_FREE)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 23.0.0.0.0 - Developer-Release
Start Date                09-SEP-2023 18:47:38
Uptime                    0 days 0 hr. 1 min. 59 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Default Service           FREE
Listener Parameter File   /opt/oracle/product/23c/dbhomeFree/network/admin/listener.ora
Listener Log File         /opt/oracle/diag/tnslsnr/6b3c2441425c/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC_FOR_FREE)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
Services Summary...
Service "FREE" has 1 instance(s).
  Instance "FREE", status READY, has 1 handler(s) for this service...
Service "FREEXDB" has 1 instance(s).
  Instance "FREE", status READY, has 0 handler(s) for this service...
Service "fb99f7d127aa0bafe0536402000a43b5" has 1 instance(s).
  Instance "FREE", status READY, has 1 handler(s) for this service...
Service "freepdb1" has 1 instance(s).
  Instance "FREE", status READY, has 1 handler(s) for this service...
The command completed successfully

The listener.ora:

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_FREE))
      (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    )
  )

DEFAULT_SERVICE_LISTENER = FREE

tnsnames.ora:

FREE =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = FREE)
    )
  )

FREEPDB1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = FREEPDB1)
    )
  )

EXTPROC_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_FREE))
    )
    (CONNECT_DATA =
      (SID = PLSExtProc)
      (PRESENTATION = RO)
    )
  )

我已经尝试过与其他自定义创建的数据库和sys用户相同的连接。此外,我尝试创建具有多个端口的容器,但没有成功。最后,我不知道这是否会有帮助,但我尝试了this,也没有运气。
我试着用oracledb python库连接:

import oracledb

connection = oracledb.connect(user="my_db_admin", password='20pwd23',
                             host="127.0.0.1", port=1521, service_name="freepdb1")

但我明白了

OperationalError: DPY-6005: cannot connect to database (CONNECTION_ID=M88go017TW5iuuV35FqWhw==).
[Errno 111] Connection refused

有人能告诉我我错过了什么,如何解决它,如果可能的话,如何更好地理解.ora文件

nzk0hqpo

nzk0hqpo1#

我想从一个问题开始:

  • 您是否在'spark-master'容器中运行Oracle数据库?*

因为,这就是通过指定localhost/127.0.0.1配置数据库连接的方式
localhost是容器的本地值。您的'spark-master'容器中没有运行数据库。它作为一个服务/容器与你的“spark-master”容器一起运行。当使用Docker compose时,* 服务发现 * 在后台发生,您可以通过名称访问它们。要联系oracle数据库服务,请提供名称oracle-localdb
现在,这应该对你有用:

import oracledb

connection = oracledb.connect(user="my_db_admin", password='20pwd23',
                             host="oracle-localdb", port=1521, service_name="freepdb1")

祝你好运!

相关问题