关于sql:为什么这个Postgres Select Query在本地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/

有问题的查询是:

1
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 app在本地调用时,上面的命令正确执行。
  • 我也可以在"docker exec -it'ing"之后使用psql将命令运行到本地的Postgres容器中。
  • Amazon RDS Postgres查询执行

  • 在生产中,我们的Rails应用程序尝试运行有问题的查询,但返回一个空数据集:{}
  • 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 / {}结果。所有其他查询似乎都有效。
  • 在上述两种情况下,查询都会正确执行。手动执行时,它会特别返回以下内容:

    1
    2
    3
    iata
    ------
    (0 ROWS)

    其他有趣的事实

  • 在生产RDS Postgres中指向本地rails容器 - 结果:Postgres返回{},即使Postgres容器可以执行相同的查询并在指向本地DB时返回预期的数据列表。在这种情况下返回的结果再现了生产行为:{}
  • SSH连接到同一VPC /安全组中与RDS DB连接的Amazon EC2实例并运行上述命令以确保它不是权限问题 - 结果:与远程查询相同:{}
  • 在两个实例上计数表(两者都返回相同的结果~5880):
    $ SELECT COUNT(*)FROM机场;
  • 列表表在Amazon RDS和本地Postgres上返回相同的表列表
  • 向前进

    在这一点上,我假设在Postgres的Amazon RDS处理数据与本地Postgres 9.6 db之间必须存在差异,但我还没有在le google上找到任何这方面的迹象。希望有些人遇到类似的事情。

    Postgres版本

    SELECT version();返回以下内容:

    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)

    StackOverflow建议与结果

    从@Aleroot修改查询到:

    1
    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;

    结果:(相同)

    1
    2
    3
     iata
    ------
    (0 ROWS)


    由于@ VaoTsun的评论最初让我走上了正确的道路,我接受了他的回答(也在这里找到)。

    真正的问题,我本应该问的,实际上最终是"如何确保我导入Amazon RDS Postgres的数据库转储完好无损?"

    这里的大部分混淆是由于Amazon RDS在导入转储时没有抛出任何错误,而且我的Rails应用程序的面向Web的部分正确地显示了几乎所有数据。

    这是因为MOST表已正确导入所有数据并且创建了所有表。因此,列出表/模式会导致一切看起来正确,并且除了一个表之外的所有查询都会得到正确的答案。

    我终于回过头来在DB中的每个表上选择了所有内容:
    SELECT * FROM each_table_name;

    一个特定的表在远程RDS数据库上没有返回任何结果,而是在本地返回预期结果。一旦发生这种情况,我将数据库从Amazon RDS中删除并重新导入所有内容。导入过程中没有错误(同样就像上次一样),但是这一次所有表都存在数据,在每个表中逐个选择所有表以验证正确导入的数据。


    正如我们在评论中所说,您可以检查结果是否不受其他表的影响。将INNER JOIN更改为OUTER JOIN将为缺少的键附加带空值的行,因此机场表的行数将满。无论是从结果中,还是通过检查regions, airports_regions, routes表上的计数,都应该揭示RDS和本地数据库之间的区别。