【问题标题】:Heroku postgres DB discards changes every time I run/deploy the application每次我运行/部署应用程序时,Heroku postgres DB 都会丢弃更改
【发布时间】:2019-10-24 07:24:48
【问题描述】:

我正在使用 python-telegram-bot 框架在 python 中开发一个用于电报的机器人。

现在它作为 dyno worker 部署在 heroku 上,我还使用 hobby-dev 计划将它链接到 Heroku Postgres DB。

问题是,每次我部署应用程序(或在本地重新运行它,本地版本也连接到同一个数据库)时,数据库会丢弃应用程序在运行时对其所做的所有更改。

一个非常奇怪的事实是,即使我添加到表中的行消失了,数据库似乎也能以某种方式跟踪这些更改,例如,“id”列的“序列”值考虑了已删除的行(见下表)。

这是数据库包含的表之一(“频道”和“创建者”列包含虚假的电报聊天 ID,因为它们与案例无关):

id |   question    |          creation          | mode | status |    channel     |  creator  
----+---------------+----------------------------+------+--------+----------------+-----------

  1 | PollQuestion1 | 2019-06-08 13:08:25.240002 | S    | t      | 0001 | 002

  2 | PollQuestion2 | 2019-06-08 13:08:26.830526 | S    | t      | 0001 | 002

  3 | PollQuestion3 | 2019-06-08 23:31:21.574572 | S    | t      | 0001 | 002

  4 | Poll4Question | 2019-06-09 16:35:58.440345 | S    | t      | 0001 | 002

  7 | PQ5           | 2019-06-09 17:42:14.172598 | S    | f      | 0001 | 002

id 为 5 和 6 的民意调查由我的应用程序添加,但在重新部署后消失了,但您可以看到我从 heroku pg:psql 终端手动添加的最后一个具有 id = 7。

这是一个与 db 交互的示例函数:

def execute_query(query):
    try:
        res = cur.execute("""{}""".format(query))
        return res
    except psycopg2.Error as e:
        logger.error("Failed executing query {0}: ({1}) {2}".format(query, e.diag.severity, e.diag.message_primary))

def test_command():
    execute_query("insert into poll (question, mode, status, channel, creator) values ('PollT1', 'S', true, '{0}', '{1}')".format(0001, 0002))

如果我随后执行了查询

"select * from Poll"

在应用程序中,可以在那里找到第一个查询的结果。

相反,如果我运行相同

"select * from Poll"

query 在本地重新部署/重新运行应用程序后,缺少 test() 函数中包含的查询结果(如您所见在上表中,我执行了两次相同的操作,因此我后来手动添加的行的 id = 7)。

我知道 heroku 采用的临时文件系统,但我也读到这不应该适用于 Heroku Postgres,因此数据库应该存储我在我的应用程序中所做的更改,尽管显然不是这样。

注意 1:我在发出“INSERT”查询和“UPDATE”查询时都遇到了这个问题。 注意 2:在执行这些操作时,我会不断监控应用程序的控制台输出,并且没有发生错误。

有没有人遇到过同样的问题并且知道如何解决或者可以指出这个问题的原因?

【问题讨论】:

    标签: python heroku heroku-postgres python-telegram-bot


    【解决方案1】:

    您需要通过调用connection.commit() 将您的更改提交到数据库。

    提交()

    向数据库提交任何待处理的事务。

    默认情况下,Psycopg 在执行第一个命令之前打开一个事务:如果不调用commit(),任何数据操作的效果都会丢失。

    假设您有一个代表您的连接对象的conn 变量,您可以在执行查询后立即调用conn.commit()。但是,确保这一点的更安全、更 Pythonic 的方法是为您的连接和光标使用 with-statement 上下文管理器。

    def execute_query(query):
        try:
            with conn:
                with conn.cursor() as cur:
                    res = cur.execute("""{}""".format(query))
                    return res
        except psycopg2.Error as e:
            logger.error("Failed executing query {0}: ({1}) {2}".format(query, e.diag.severity, e.diag.message_primary))
    
    

    如果查询成功,它会自动调用commit(),如果查询不成功,它会自动调用rollback()

    【讨论】:

      猜你喜欢
      • 2012-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多