2

设置 - PHP 7 应用程序。- Postgres 在 Heroku Hobby v11.x 上 - MySQL 版本是 v5.5.56 和协议 10 - 我对 PHP 不太了解 - 我对低级 Postgres 转换没有深入了解。

我使用 pgloader 从 MySQL 迁移到 Postgres。

pgloader --dry-run --with 'create indexes' --with 'create indexes' --with 'foreign keys' --with 'downcase identifiers'  --with 'create tables' --with 'include drop' mysql://<<hidden>>@us-cdbr-iron-east-03.cleardb.net/heroku_509e1e230baf4be postgres://<<hidden>>@ec2-23-21-177-102.compute-1.amazonaws.com:5432/dflfjbhhq18cav?sslmode=require

我知道连接正常。在将 MySQL 函数与 Postgres 交换后,一些查询正在工作 - 我知道这一点,因为我可以看到数据填充。我还必须进行一些调整才能使查询正常工作。

复制字段的查询具有有效的 SQL 语句,但出现以下错误。我知道这个查询很好,因为我已经将它回显并粘贴到我的 Navicat SQL 窗口中,它会产生正确的结果。

pg_query(): Query failed: ERROR:  permission denied for table campaigns

DB 用户似乎拥有访问campaigns表并获得所需内容的所有适当权限。

我继续寻找另一个非常奇怪的问题。

无论我使用什么来尝试使用有效的 SQL 语句使用 PHP 运行查询,我都没有得到任何数据。
-pg_pquery -pg_fetch_array -pg_query_params -pg_fetch_array

请参阅下面的代码示例。

//Get the existing number of quota_deducted
    $q = 'SELECT app, quota_deducted FROM campaigns WHERE id = '.$campaign_id;
    $r = pg_query($mysqli, $q);
    if ($r) 
    {
        while($row = pg_fetch_array($r)) 
        {
            $app = $row['app'];
            $current_quota_deducted = $row['quota_deducted']=='' ? 0 : $row['quota_deducted'];
        }

        //Check if monthly quota needs to be updated
        $q2 = 'SELECT allocated_quota, current_quota FROM apps WHERE id = '.$app;
        $r2 = pg_query($mysqli, $q2);
        if($r2) 
        {
            while($row2 = pg_fetch_array($r2)) 
            {
                $allocated_quota = $row2['allocated_quota'];
                $current_quota = $row2['current_quota'];
            }
        }
        $updated_quota = $current_quota - $current_quota_deducted;

        //Update quota if a monthly limit was set
        if($allocated_quota!=-1)
        {           
            //if so, update quota
            $q3 = 'UPDATE apps SET current_quota = '.$updated_quota.' WHERE id = '.$app;
            pg_query($mysqli, $q3);
        }
    }

我在 apache2 终端窗口的尾随日志中看到错误,但在数据库 pgAdmin 上看不到任何实际连接或活动。

Heroku DB 上的日志似乎也没有出现?不确定这是否是因为它只是一个爱好。

我已经检查了所有明显的东西,比如确保我们连接到正确的数据库等等。

使用 Navicate 时,我在尝试调用表 DESIGN 函数时遇到了以前从未见过的错误。我收到以下错误。不确定这是否对上述问题有影响。我能够测试其他相同版本的 Postgres,发现下面的这个错误不存在。因此,也许 pgloader 正在创建一些无法解决的低级别问题。

ERROR: Column "proisagg" doe snot exist
LINE 1: ...e JOIN pg_language lng ON lng.oid=p.prolang WHERE proisagg = .. 
HINT: Perhaps you meant to reference the column "p.prolang".

这是我们尝试运行的查询。这在 Navicat 中确实有效。


INSERT INTO campaigns (userid, app, from_name, from_email, reply_to, title, label, plain_text, html_text, query_string, bounce_setup, complaint_setup, wysiwyg, opens_tracking, links_tracking) VALUES (2, 152, 'Person Name', 'campaignsupport@company.com', 'campaignsupport@company.com', 'Test', '', 'Test plain text.', 'asdf', '', 0, 0, 1, 1, 1)

或者


INSERT INTO public.campaigns (userid, app, from_name, from_email, reply_to, title, label, plain_text, html_text, query_string, bounce_setup, complaint_setup, wysiwyg, opens_tracking, links_tracking) VALUES (2, 152, 'Person Name', 'campaignsupport@company.com', 'campaignsupport@company.com', 'Test', '', 'Test plain text.', 'asdf', '', 0, 0, 1, 1, 1)

在过去的 20 个小时里,我一直在研究这个问题,我很难过任何帮助或想法都会得到很大的帮助。

温馨问候,

凯西哈弗诺

4

1 回答 1

1

您的问题包含大量问题,并且没有足够的信息来完全解决其中任何一个问题,因此我将尝试提供一些故障排除步骤,以帮助您找到解决方案。

问题 #1

命令:

INSERT INTO campaigns (userid, app, from_name, from_email, reply_to, title, label, plain_text, html_text, query_string, bounce_setup, complaint_setup, wysiwyg, opens_tracking, links_tracking) VALUES (2, 152, 'Person Name', 'campaignsupport@company.com', 'campaignsupport@company.com', 'Test', '', 'Test plain text.', 'asdf', '', 0, 0, 1, 1, 1)

失败并出现错误:

pg_query(): Query failed: ERROR:  permission denied for table campaigns

但是,当您在 Navicat 中运行此 SQL 命令时,您可以执行它。

在您描述的上下文中,发生此错误的原因只有几个:

  • 您没有使用具有所需权限的用户(可能不是您认为您连接的用户)连接到数据库。要检查您与问题查询连接的用户:

    SELECT current_user;
    

    使用与失败查询相同的连接,在您的应用程序中,在失败查询之前立即发出此命令。将输出记录在您可以看到的地方 - 例如。apache错误日志。

    从 Navicat 发出相同的查询以查看在那里使用的用户。如果与应用程序使用的不同,则重新连接同一用户并查看查询是否仍然失败。

  • 该表没有您认为它具有的权限授予。

    我不熟悉 Navicat:它可能提供检查表权限的方法。如果没有(或者如果它不起作用,请参见下文),那么您可以使用psql命令行工具进行连接并使用命令\z campaigns 查看表上的授权集。

  • 您没有访问您认为自己是的表,可能需要与您认为正在访问的表不同的权限。如果模式路径导致选择了不同模式中的同名表,则可能会发生这种情况。但是我认为这不会发生,因为您提到您已尝试指定完全限定名称public.campaigns

  • 您没有连接到正确的数据库。您声明您已经检查了这一点 - 如果您已经达到了这一点,但仍然没有找到原因,我建议您再次检查!

问题 #2

无论我使用什么来尝试使用有效的 SQL 语句使用 PHP 运行查询,我都没有得到任何数据。

简化后,您的代码如下所示:

$r = pg_query($mysqli, $q);
if ($r) 
{
    // do something
}

我不是 php 专家,但检查文档pg_query发现它说:

如果发生错误并返回 FALSE,如果连接有效,则可以使用 pg_last_error() 函数检索错误的详细信息。

您没有检查任何错误情况。我猜想查询失败了,可能与上面提到的权限问题相同。我建议else在调用pg_last_error()和显示结果的代码中添加一个子句。

问题 #3

Navicat 显示此错误:

ERROR: Column "proisagg" doe snot exist
LINE 1: ...e JOIN pg_language lng ON lng.oid=p.prolang WHERE proisagg = .. 
HINT: Perhaps you meant to reference the column "p.prolang".

直到 postgresql 11,内部 postgresql 表pg_proc包含一个列 proisagg,如果该行表示聚合函数,则该列为真。

从 Postgresql 11 开始,此列被替换为prokind具有不同值的列,以描述该行是否代表聚合函数、窗口函数、普通函数或过程。

如上所述,我不熟悉 Navicat,但我猜您使用的版本尚未更新以考虑此更改。

于 2019-07-26T06:45:27.257 回答