Заполнение нулевых значений в sqlite3 значением той же строки, но следующего столбца в Python

У меня есть база данных в sqlite, теперь при вставке в эти данные некоторые пробелы определяются как null. Мне нужен скрипт, который находит нули и помещает значение той же строки, но следующий столбец в нулевое значение для заполнения (значение справа).
на питоне
Заполнение нулевых значений в sqlite3 значением той же строки, но следующего столбца в Python

# Fetch all data from your table
cursor.execute("SELECT * FROM my_table")
rows = cursor.fetchall()

# Get the column names
column_names = [description[0] for description in cursor.description]

# Loop through each row and update NULL values
for row in rows:
    # Prepare the data to be updated
    updated_row = list(row)

    # Replace NULL values with the value to the right
    for i in range(len(updated_row) - 1):
        if updated_row[i] is None:
            # Find the next non-NULL value to the right
            for j in range(i + 1, len(updated_row)):
                if updated_row[j] is not None:
                    updated_row[i] = updated_row[j]
                    break

    # Update the row in the database
    update_query = f"UPDATE your_table_name SET {', '.join(f'{col} = ?' for col in column_names)} WHERE rowid = ?"
    cursor.execute(update_query, (*updated_row, row[0]))  # Assuming the first column is the rowid

но у меня есть эта ошибка:

   cursor.execute(update_query, (*updated_row, row[0]))  # Assuming the first column is the rowid
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: near "20553975": syntax error

🤔 А знаете ли вы, что...
Синтаксис Python известен своей простотой и читаемостью.


50
2

Ответы:

Похоже, вы используете цифры в качестве имени столбца...
Из документации:
Соглашения об именах в SQLite

Соглашение об именах — это набор правил для выбора последовательности символов, которая будет использоваться для идентификаторов, обозначающих имя базы данных, таблицы, столбца, индекса, триггера или представления в SQLite.

Допустимые символы: Имя идентификатора должно начинаться с буквы или символа подчеркивания, за которым следует любой буквенно-цифровой символ или символ подчеркивания. Другие символы недопустимы.


Решено

Хорошо, здесь есть несколько проблем. Прежде всего, как указано в другом ответе, числовые имена столбцов запрещены. Вы можете использовать их, но это не рекомендуется и может привести к неожиданному поведению. Самый простой способ исправить это — заключить их в обратные кавычки, чтобы получить ', '.join(f'`{col}` = ?' for col in column_names).

Хотя в целом было бы гораздо предпочтительнее обновлять только те столбцы, которые действительно изменяются. Итак, рассмотрим

cursor.execute("SELECT * FROM my_table")
rows = cursor.fetchall()
column_names = [description[0] for description in cursor.description]

# you only need to count once
colcount = len(column_names)

for row in rows
    # Use a dict to store the columns that need changing and their values.
    # Nowadays the dict() builtin provides an OrderedDict, which has benefits
    updated_row = dict()
    # Only update nulls
    for i in range(colcount):
        if row[i] is None:
            j = i + 1
            while j < colcount:
                # check the next column if available
                if row[j] is not None:
                    updated_row[column_names[i]] = row[j]
                    break
                j += 1
            # if break is never called, there is no non-null. Default to 0
            else:
                updated_row[column_names[i]] = 0

    update_query = f"""
                   UPDATE your_table_name
                   SET {', '.join(f'`{col}` = ?' for col in updated_row)}
                   WHERE rowid = ?
                   """
    cursor.execute(update_query, (*updated_row.values(), row[0]))