Docker环境下PySpark读取PostgreSQL无数据及报错求助
PostgreSQL数据读取问题排查(PySpark ETL项目)
环境配置(docker-compose.yml)
version: "3.3" services: spark-master: image: docker.io/bitnami/spark:3.3 ports: - "9090:8080" - "7077:7077" volumes: - /opt/spark-apps - /opt/spark-data environment: - SPARK_LOCAL_IP=spark-master - SPARK_WORKLOAD=master spark-worker-a: image: docker.io/bitnami/spark:3.3 ports: - "9091:8080" - "7000:7000" depends_on: - spark-master environment: - SPARK_MASTER=spark://spark-master:7077 - SPARK_WORKER_CORES=1 - SPARK_WORKER_MEMORY=1G - SPARK_DRIVER_MEMORY=1G - SPARK_EXECUTOR_MEMORY=1G - SPARK_WORKLOAD=worker - SPARK_LOCAL_IP=spark-worker-a volumes: - /opt/spark-apps - /opt/spark-data spark-worker-b: image: docker.io/bitnami/spark:3.3 ports: - "9092:8080" - "7001:7000" depends_on: - spark-master environment: - SPARK_MASTER=spark://spark-master:7077 - SPARK_WORKER_CORES=1 - SPARK_WORKER_MEMORY=1G - SPARK_DRIVER_MEMORY=1G - SPARK_EXECUTOR_MEMORY=1G - SPARK_WORKLOAD=worker - SPARK_LOCAL_IP=spark-worker-b volumes: - /opt/spark-apps - /opt/spark-data postgres: container_name: postgres_container image: postgres:11.7-alpine environment: POSTGRES_USER: admin POSTGRES_PASSWORD: admin volumes: - /data/postgres ports: - "4560:5432" restart: unless-stopped # jupyterlab with pyspark jupyter-pyspark: image: jupyter/pyspark-notebook:latest environment: JUPYTER_ENABLE_LAB: "yes" ports: - "9999:8888" volumes: - /app/data
问题现象
已成功连接数据库,但读取sales表时遇到两个问题:
1. 链式调用.show().toPandas()触发报错
使用的PySpark代码:
from pyspark.sql import SparkSession spark = SparkSession.builder\ .appName("salesETL")\ .config("spark.driver.extraClassPath", "./postgresql-42.5.1.jar")\ .getOrCreate() df = spark.read.format("jdbc").option("url", "jdbc:postgresql://postgres_container:5432/postgres")\ .option("dbtable", "sales")\ .option("driver", "org.postgresql.Driver")\ .option("user", "admin")\ .option("password", "admin").load() df.show(10).toPandas()
报错信息:
AttributeError Traceback (most recent call last) Cell In[7], line 1 ----> 1 df.show(10).toPandas() AttributeError: 'NoneType' object has no attribute 'toPandas'
2. 仅显示表结构,无数据返回
执行df.show(10)后输出:
+--------+----------+-----------+-------------+-----------------+-------------+--------------+----------+--------+-----------+ |order_id|order_date|customer_id|customer_name|customer_lastname|customer_city|customer_state|product_id|quantity|order_value| +--------+----------+-----------+-------------+-----------------+-------------+--------------+----------+--------+-----------+ +--------+----------+-----------+-------------+-----------------+-------------+--------------+----------+--------+-----------+
执行type(df)返回pyspark.sql.dataframe.DataFrame,确认DataFrame对象存在。
问题排查与解决
1. .show().toPandas()报错的修复
df.show()仅用于在控制台打印数据,返回值为None,无法链式调用.toPandas()。正确写法是分开执行:
df.show(10) # 打印数据到控制台 pandas_df = df.toPandas() # 转换为Pandas DataFrame
2. 无数据返回的排查步骤
(1)验证PostgreSQL表中是否存在数据
进入PostgreSQL容器直接查询:
# 进入postgres容器 docker exec -it postgres_container psql -U admin postgres # 查询sales表数据 SELECT * FROM sales LIMIT 10;
如果查询结果为空,说明表本身无数据,需先导入数据。
(2)检查JDBC连接的数据库与表名
确认JDBC URL中的数据库名(postgres)正确,且该数据库下确实存在sales表。若表在其他数据库中,需修改URL中的数据库名称。
(3)修复PostgreSQL驱动包路径问题
代码中指定的./postgresql-42.5.1.jar可能在Jupyter容器中不存在:
- 将驱动包放置到Jupyter容器挂载的
/app/data目录(对应docker-compose中的卷配置); - 修改SparkSession配置,使用
spark.jars确保驱动包被正确加载:spark = SparkSession.builder\ .appName("salesETL")\ .config("spark.jars", "/app/data/postgresql-42.5.1.jar")\ .getOrCreate()
(4)验证容器网络连通性
在Jupyter容器中测试与PostgreSQL容器的连通性:
# 进入jupyter-pyspark容器 docker exec -it <jupyter_container_id> bash # 测试网络可达性 ping postgres_container # 使用psql测试数据库连接 psql -h postgres_container -U admin -d postgres -c "SELECT * FROM sales LIMIT 10;"
若网络不通,需检查docker-compose的网络配置(默认同一网桥下容器互通,自定义网络需确认配置)。
内容的提问来源于stack exchange,提问作者Luis Felipe
相关产品推荐
相关产品推荐

