Heroku postgres DB отменяет изменения каждый раз, когда я запускаю / развертываю приложение - PullRequest
1 голос
/ 09 июня 2019

Я разрабатываю бота на python для telegram с использованием фреймворка python-telegram-bot.

Сейчас он развернут на heroku в качестве динамо-работника, и я также связал его с базой данных Heroku Postgres, используя план hobby-dev.

Проблема в том, что каждый раз, когда я развертываю приложение (или перезапускаю его локально, локальная версия также подключается к той же БД), БД сбрасывает все изменения, которые приложение вносит в него во время работы.

Очень странным фактом является то, что БД как-то отслеживает эти изменения, даже если строки, которые я добавляю в таблицы, исчезают, как, например, значение "serial" столбца '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

Опросы с идентификаторами 5 и 6 были добавлены моим приложением, но исчезли после повторного развертывания, но, как вы можете видеть, последний добавленный мной вручную из heroku pg: psql терминал имеет id = 7.

Это примерная функция, которая взаимодействует с БД:

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. Во время выполнения этих операций я постоянно отслеживаю вывод консоли приложения, и никаких ошибок не возникает.

Кто-нибудь имел такую ​​же проблему и знает, как ее решить, или может указать мне причину этой проблемы?

1 Ответ

1 голос
/ 09 июня 2019

Вам необходимо зафиксировать свои изменения в базе данных, позвонив по номеру 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(), если запрос неуспешен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...