You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache AGE容器自动化测试中cypher函数未识别问题

自动化Apache AGE单元测试遇到的Cypher函数未识别问题

问题背景

我正在开发基于Apache AGE的Python模块,需要编写单元测试。为此写了bash脚本实现自动化流程:拉取apache/age镜像启动Docker容器,复制SQL配置文件到容器内执行,运行Python测试脚本,最后停止并删除容器,方便快速排查错误。

现有自动化脚本

test_script.sh

#!/bin/bash

# 启动Apache AGE容器
docker pull apache/age
docker run \
    --name myPostgresDb  \
    -p 5455:5432 \
    -e POSTGRES_USER=postgresUser \
    -e POSTGRES_PASSWORD=postgresPW \
    -e POSTGRES_DB=postgresDB \
    -d \
    apache/age
sleep 3

# 复制SQL脚本到容器内
docker cp tests/setup_age.sql myPostgresDb:/setup_age.sql
sleep 1

# 在容器内执行SQL脚本
docker exec -i myPostgresDb psql -U postgresUser -d postgresDB -f /setup_age.sql
sleep 1

# 执行Python测试脚本
python3 -m tests.test

# 停止并删除容器
docker stop myPostgresDb
docker rm myPostgresDb

setup_age.sql

LOAD 'age';
SET search_path = ag_catalog, "$user", public;

错误情况

SQL脚本执行成功,但Python测试脚本执行以下查询时:

SELECT * FROM cypher('graph', $$
CREATE (n:label)
$$) as (n agtype);

出现错误:

psycopg2.errors.UndefinedFunction: function cypher(unknown, unknown) does not exist
LINE 2: SELECT * FROM cypher('graph', $$
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

手动进入容器终端执行配置语句和测试查询可正常运行,但自动化流程无法正常工作,手动操作耗时较长。

补充脚本输出

Using default tag: latest
latest: Pulling from apache/age
Digest: sha256:5134806b5de7d16e0123fba928f7992064b4eebaeb9f2cae225ad4f5b5475a33
Status: Image is up to date for apache/age:latest
docker.io/apache/age:latest

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview apache/age
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
7bbe43007dbac2185ef6da73e4e503e61deade3651f470c04611c6531c41a3f0
                                             Successfully copied 2.05kB to myPostgresDb:/setup_age.sql
LOAD
SET

解决方案

核心问题是会话级别的search_path设置未持久化:通过docker exec执行的SET search_path仅对当前psql会话生效,而Python测试脚本是新建的数据库连接,不会继承该设置。

方法1:在Python测试脚本中配置会话参数

在建立数据库连接后,先执行加载扩展和设置search_path的语句,确保当前会话生效:

import psycopg2

# 建立数据库连接
conn = psycopg2.connect(
    dbname="postgresDB",
    user="postgresUser",
    password="postgresPW",
    host="localhost",
    port="5455"
)
cur = conn.cursor()

# 加载AGE扩展并设置search_path
cur.execute("LOAD 'age';")
cur.execute("SET search_path = ag_catalog, \"$user\", public;")
conn.commit()

# 执行Cypher查询
cur.execute("""
SELECT * FROM cypher('graph', $$
CREATE (n:label)
$$) as (n agtype);
""")

方法2:全局持久化search_path配置

修改自动化脚本,将search_path写入PostgreSQL的配置文件,使所有新连接自动应用该设置:
在test_script.sh的docker cp步骤之后、docker exec执行SQL脚本之前,添加以下内容:

# 修改postgresql.conf,添加全局search_path配置
docker exec -i myPostgresDb bash -c "echo 'search_path = ag_catalog, \"\$user\", public' >> /var/lib/postgresql/data/postgresql.conf"
# 重启PostgreSQL服务使配置生效
docker exec -i myPostgresDb pg_ctl -D /var/lib/postgresql/data restart
sleep 2

额外优化建议

  • 脚本中的固定sleep时间可能不足以让PostgreSQL完全启动(尤其是跨平台运行镜像时),可以替换为等待数据库就绪的逻辑:
# 等待PostgreSQL服务就绪
until docker exec myPostgresDb psql -U postgresUser -d postgresDB -c "SELECT 1;" > /dev/null 2>&1; do
    sleep 1
done

这样能避免固定sleep的不确定性,确保数据库完全启动后再执行后续操作。

内容的提问来源于stack exchange,提问作者Matheus Farias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:00:19