为什么此 Postgres Select 查询在本地 Docker 容器中有效,但在 Amazon RDS Postgres 中无效?
Why does this Postgres Select Query work in the local Docker Container but not on Amazon RDS Postgres?
我的团队有一个本地开发环境,其中包含一个 Ruby on Rails 应用程序,该应用程序连接到 Postgres 数据库以检索有关机场的一些信息并使用该信息进行进一步查询。本地环境旨在复制我们的生产环境(都 运行 在同一个 docker 容器中)。
本地 Postgres 容器正在使用官方 Postgres:9.6-alpine 容器,可在此处找到:https://hub.docker.com/_/postgres/
有问题的查询是:
SELECT airports.iata FROM "routes" INNER JOIN "regions" ON "regions"."id" = "routes"."origin_id" INNER JOIN "airports_regions" ON "airports_regions"."region_id" = "regions"."id" INNER JOIN "airports" ON "airports"."id" = "airports_regions"."airport_id";
本地查询执行
- 当我们的 rails 应用在本地调用时,上述命令会正确执行。
- 我也可以 运行 在 "docker exec -it'ing" 之后使用 psql 命令到本地的 Postgres 容器中。
Amazon RDS Postgres 查询执行
- 在生产中,我们的 Rails 应用程序尝试 运行 有问题的查询,但 return 是一个空数据集:{}
It should be noted that it successfully connects to the DB and
"successfully" makes the query after properly authenticating, so
really the issue here is that the query doesn't properly return / match the data.
- 当我使用 psql 手动连接到我们的 Amazon RDS Postgres 数据库时,我可以正确进行身份验证,并且可以执行查询,但我再次收到 null / {} 结果。所有其他查询似乎都有效。
在上述两种情况下,查询都能正确执行。手动执行时,它具体 return 如下:
iata
------
(0 rows)
其他有趣的事实
- 指向生产 RDS Postgres 的本地 rails 容器 - 结果:Postgres returns {} 即使 Postgres 容器可以执行相同的查询和 return 预期的数据列表指向本地数据库。在这种情况下返回的结果重现了生产行为:{}
- SSH 到连接到同一 VPC/安全组中的 RDS 数据库的 Amazon EC2 实例和 运行 上面的命令以确保它不是权限问题 — 结果:与远程查询相同:{}
- 计算两个实例的 table(两个 return 相同的结果 ~5880):
$ SELECT COUNT(*) 来自机场;
- 列表 tables returns 在 Amazon RDS 和本地 Postgres 上相同的 table 列表
前进
在这一点上,我假设 Amazon RDS for Postgres 处理数据的方式与本地 Postgres 9.6 数据库之间一定存在差异,但我无法在 le google。希望有些人 运行 变成了类似的东西。
Postgres 版本
SELECT 版本(); return如下:
RDS Postgres 版本
PostgreSQL 9.6.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.2
20140120 (Red Hat 4.8.2-16), 64-bit (1 row)
本地 Postgres 版本
PostgreSQL 9.6.3 on x86_64-pc-linux-musl, compiled by gcc (Alpine
6.2.1) 6.2.1 20160822, 64-bit (1 row)
带结果的 Whosebug 建议
来自@Aleroot 修改查询为:
SELECT a.iata FROM routes ru JOIN regions re ON re.id = ru.origin_id JOIN airports_regions ar ON ar.region_id = re.id JOIN airports a ON a.id = ar.airport_id;
结果:(相同)
iata
------
(0 rows)
正如我们在评论中所说,您可以检查结果是否不受其他 table 的影响。将 INNER JOIN
更改为 OUTER JOIN
将为缺少的键追加带有空值的行,因此机场的行数 table 将填满。无论是从结果,还是仅仅通过检查 regions, airports_regions, routes
tables 上的计数,都应该揭示 RDS 和本地数据库之间的差异。
因为@VaoTsun 的评论最初让我走上了正确的道路,所以我接受了他的回答(也可以在这里找到)。
真正的问题,我应该问的,实际上是 "How can I make sure that a DB dump that I imported into Amazon RDS Postgres is intact?"
这里的大部分混乱是因为 Amazon RDS 在我导入转储时没有抛出任何错误,而且我的 Rails 应用程序的面向 Web 的部分正确显示了几乎所有数据。
这是因为大多数 tables 都与所有数据一起正确导入,并且创建了所有 tables。因此,列出 tables / 模式导致一切看起来都是正确的,并且除了一个 table 之外的所有查询都得到了正确的答案。
我终于回过头来在数据库中的每个 table 上选择了全部:
SELECT * 来自 each_table_name;
一个特定的 table 在远程 RDS 数据库上没有返回任何结果,而它在本地返回了预期的结果。发生这种情况后,我将数据库从 Amazon RDS 中删除并重新导入所有内容。导入过程中没有错误(再次像上次一样)但是这次所有 table 都存在数据,在每个 table 中一一选择所有以验证正确导入的数据。
我的团队有一个本地开发环境,其中包含一个 Ruby on Rails 应用程序,该应用程序连接到 Postgres 数据库以检索有关机场的一些信息并使用该信息进行进一步查询。本地环境旨在复制我们的生产环境(都 运行 在同一个 docker 容器中)。
本地 Postgres 容器正在使用官方 Postgres:9.6-alpine 容器,可在此处找到:https://hub.docker.com/_/postgres/
有问题的查询是:
SELECT airports.iata FROM "routes" INNER JOIN "regions" ON "regions"."id" = "routes"."origin_id" INNER JOIN "airports_regions" ON "airports_regions"."region_id" = "regions"."id" INNER JOIN "airports" ON "airports"."id" = "airports_regions"."airport_id";
本地查询执行
- 当我们的 rails 应用在本地调用时,上述命令会正确执行。
- 我也可以 运行 在 "docker exec -it'ing" 之后使用 psql 命令到本地的 Postgres 容器中。
Amazon RDS Postgres 查询执行
- 在生产中,我们的 Rails 应用程序尝试 运行 有问题的查询,但 return 是一个空数据集:{}
It should be noted that it successfully connects to the DB and "successfully" makes the query after properly authenticating, so really the issue here is that the query doesn't properly return / match the data.
- 当我使用 psql 手动连接到我们的 Amazon RDS Postgres 数据库时,我可以正确进行身份验证,并且可以执行查询,但我再次收到 null / {} 结果。所有其他查询似乎都有效。
在上述两种情况下,查询都能正确执行。手动执行时,它具体 return 如下:
iata
------
(0 rows)
其他有趣的事实
- 指向生产 RDS Postgres 的本地 rails 容器 - 结果:Postgres returns {} 即使 Postgres 容器可以执行相同的查询和 return 预期的数据列表指向本地数据库。在这种情况下返回的结果重现了生产行为:{}
- SSH 到连接到同一 VPC/安全组中的 RDS 数据库的 Amazon EC2 实例和 运行 上面的命令以确保它不是权限问题 — 结果:与远程查询相同:{}
- 计算两个实例的 table(两个 return 相同的结果 ~5880): $ SELECT COUNT(*) 来自机场;
- 列表 tables returns 在 Amazon RDS 和本地 Postgres 上相同的 table 列表
前进
在这一点上,我假设 Amazon RDS for Postgres 处理数据的方式与本地 Postgres 9.6 数据库之间一定存在差异,但我无法在 le google。希望有些人 运行 变成了类似的东西。
Postgres 版本
SELECT 版本(); return如下:
RDS Postgres 版本
PostgreSQL 9.6.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16), 64-bit (1 row)
本地 Postgres 版本
PostgreSQL 9.6.3 on x86_64-pc-linux-musl, compiled by gcc (Alpine 6.2.1) 6.2.1 20160822, 64-bit (1 row)
带结果的 Whosebug 建议
来自@Aleroot 修改查询为:
SELECT a.iata FROM routes ru JOIN regions re ON re.id = ru.origin_id JOIN airports_regions ar ON ar.region_id = re.id JOIN airports a ON a.id = ar.airport_id;
结果:(相同)
iata
------
(0 rows)
正如我们在评论中所说,您可以检查结果是否不受其他 table 的影响。将 INNER JOIN
更改为 OUTER JOIN
将为缺少的键追加带有空值的行,因此机场的行数 table 将填满。无论是从结果,还是仅仅通过检查 regions, airports_regions, routes
tables 上的计数,都应该揭示 RDS 和本地数据库之间的差异。
因为@VaoTsun 的评论最初让我走上了正确的道路,所以我接受了他的回答(也可以在这里找到)。
真正的问题,我应该问的,实际上是 "How can I make sure that a DB dump that I imported into Amazon RDS Postgres is intact?"
这里的大部分混乱是因为 Amazon RDS 在我导入转储时没有抛出任何错误,而且我的 Rails 应用程序的面向 Web 的部分正确显示了几乎所有数据。
这是因为大多数 tables 都与所有数据一起正确导入,并且创建了所有 tables。因此,列出 tables / 模式导致一切看起来都是正确的,并且除了一个 table 之外的所有查询都得到了正确的答案。
我终于回过头来在数据库中的每个 table 上选择了全部: SELECT * 来自 each_table_name;
一个特定的 table 在远程 RDS 数据库上没有返回任何结果,而它在本地返回了预期的结果。发生这种情况后,我将数据库从 Amazon RDS 中删除并重新导入所有内容。导入过程中没有错误(再次像上次一样)但是这次所有 table 都存在数据,在每个 table 中一一选择所有以验证正确导入的数据。