kan3k1k3n
@kan3k1k3n

Как сделать так, чтобы данные, которые я пишу в тг бота, заполняли сперва первую строчку в таблице postgre?

есть фрагмент кода, который вносит данные в таблицу, которую ты сам же и создал с помощью бота:
@bot.message_handler(commands=['insert_data'])
def get_column_name(message):
    db_name = connect_text.get('dbname', '...')
    user_name = connect_text.get('user', '...')
    password = connect_text.get('password', '...')
    tableName = table_name.get('t_name', '...')
    conn = psycopg2.connect(dbname=db_name, user=user_name, password=password, host='127.0.0.1')
    cur = conn.cursor()
    cur.execute(f"SELECT column_name FROM information_schema.columns WHERE table_name='{tableName}'")
    rows = cur.fetchall()
    column_names = [row[0] for row in rows]
    global column_names_str
    column_names_str = "\n".join(column_names)
    bot.send_message(message.chat.id, f'выберите колонку, в которую хотите внести данные:\n{column_names_str}')
    bot.register_next_step_handler(message, get_column_value, column_names)

def get_column_value(message, column_names):
    column_name = message.text.strip()
    if column_name not in column_names:
        bot.send_message(message.chat.id, 'некорректное название колонки. попробуйте еще раз.')
        bot.register_next_step_handler(message, get_column_value, column_names)
        return
    bot.send_message(message.chat.id, f'введите данные для колонки {column_name}:')
    bot.register_next_step_handler(message, insert_data, column_name, column_names)

def insert_data(message, column_name, column_names):
    db_name = connect_text.get('dbname', '...')
    user_name = connect_text.get('user', '...')
    password = connect_text.get('password', '...')
    tableName = table_name.get('t_name', '...')
    conn = psycopg2.connect(dbname=db_name, user=user_name, password=password, host='127.0.0.1')
    cur = conn.cursor()
    data = message.text.strip()
    cur.execute(f"INSERT INTO {tableName} ({column_name}) VALUES ('{data}')")
    conn.commit()
    bot.send_message(message.chat.id, f'данные "{data}" успешно добавлены в колонку {column_name}!\nхотите добавить что-то еще? (y/n)')
    bot.register_next_step_handler(message, get_answer, column_names)

def get_answer(message, column_names):
    answer = message.text
    if answer == 'y':
        bot.send_message(message.chat.id, f'выберите колонку, в которую хотите внести данные:\n{column_names_str}')
        bot.register_next_step_handler(message, get_column_value, column_names)
    else:
        bot.send_message(message.chat.id, 'хорошо')

все работает, но есть одно но: когда я заполняю другой столбец, до данные вносятся на новую строчку

64b036327bbcd404556258.png
как выглядят сообщения в боте:

64b036b139029890153059.png
как сделать так, чтобы сначала заполнялась вся первая строка, а потом предыдущая? (с учетом того, что я не пишу запрос "insert into ... where ... = ...")
  • Вопрос задан
  • 141 просмотр
Пригласить эксперта
Ответы на вопрос 3
Vindicar
@Vindicar
RTFM!
Почитай хотя бы про основы реляционных БД.
У каждой таблицы должен быть первичный ключ - иными словами, такое поле/комбинация полей, которая будет уникальной для каждой записи.
Тогда алгоритм будет такой: спрашиваешь пользователя, какую запись он хочет редактировать, запоминаешь её ключ, затем переходишь в режим редактирования, где поочерёдно спрашиваешь значения столбцов.
Подразумевается, что ты знаешь, как сделать сценарий, чтобы бот последовательные сообщения обрабатывал по-разному. Если не знаешь - читай, как реализуется finite state machine (FSM) в выбранной тобой библиотеке.
Ну и да:
data = message.text.strip()
cur.execute(f"INSERT INTO {tableName} ({column_name}) VALUES ('{data}')")

Это - готовая SQL инъекция. И если вставку tableName и column_name еще можно оправдать (хотя ты их тоже не проверяешь на допустимость), то данные так вставлять нельзя. Есть правильный способ.
Ответ написан
Комментировать
mayton2019
@mayton2019
Bigdata Engineer
Ну в базах данных так не делают. Обычно все колонки именованы и имеют смысл.

У тебя есть два варианта КМК. Можно провести еще один сеанс нормализации и сделать табличку
так.

id| q  | value
1 | q1 | 1111....
1 | q2 | 2222....
1 | q3 | 3333333
2 | q1 |......


или сделать value как JSON и складывать туда массив

id| json_value
1 | [ "11111", "2222", "333333" ....]
Ответ написан
Комментировать
@kalapanga
Добавление новой записи - это insert. Редактирование существующей записи - это update.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы