处理数据库更新中的无值

问题描述 投票:0回答:1

我正在开发一个Python应用程序,我需要根据用户提供的设置更新数据库记录。我有一个方法

saveSettings
可以更新数据库中的各种设置,但我在处理
None
值时遇到问题。

这是我的方法版本:

def saveSettings(self, name, font_size=None, bg_color=None, font_color=None, title_header=None, sorting_header=None):
    if not self._taskboard_exists(name):
        raise Exception(f"Taskboard '{name}' does not exist.")

    with self.global_db:
        cursor = self.global_db.cursor()

        # Check if the 'font_size', 'bg_color', 'font_color', 'title_header', and 'sorting_header' columns exist in the configuration table
        cursor.execute(f"PRAGMA table_info('{name}')")
        columns = cursor.fetchall()
        column_names = [column[1] for column in columns]

        # If any of the parameters are provided and the corresponding column doesn't exist, create it
        if font_size is not None and 'font_size' not in column_names:
            cursor.execute(f"ALTER TABLE '{name}' ADD COLUMN 'font_size' TEXT")
        if bg_color is not None and 'bg_color' not in column_names:
            cursor.execute(f"ALTER TABLE '{name}' ADD COLUMN 'bg_color' TEXT")
        if font_color is not None and 'font_color' not in column_names:
            cursor.execute(f"ALTER TABLE '{name}' ADD COLUMN 'font_color' TEXT")
        if title_header is not None and 'title_header' not in column_names:
            cursor.execute(f"ALTER TABLE '{name}' ADD COLUMN 'title_header' TEXT")
        if sorting_header is not None and 'sorting_header' not in column_names:
            cursor.execute(f"ALTER TABLE '{name}' ADD COLUMN 'sorting_header' TEXT")

        # Update the font size, background color, font color, title header, and sorting header in the configuration table for the taskboard
        update_query = f"UPDATE '{name}' SET "
        update_values = []

        if font_size is not None:
            update_query += "font_size = ?, "
            update_values.append(font_size)
        if bg_color is not None:
            update_query += "bg_color = ?, "
            update_values.append(bg_color)
        if font_color is not None:
            update_query += "font_color = ?, "
            update_values.append(font_color)
        if title_header is not None:
            update_query += "title_header = ?, "
            update_values.append(title_header)
        if sorting_header is not None:
            update_query += "sorting_header = ?, "
            update_values.append(sorting_header)

        # Remove the trailing comma and space from the query
        if update_query.endswith(", "):
            update_query = update_query[:-2]

        # Execute the update query with the values
        if update_values:
            cursor.execute(update_query, update_values)
            self.global_db.commit()

问题是,当任何参数为

None
时,该方法会将数据库中相应的值设置为空,这不是我想要的行为。相反,我想确保如果一个参数是
None
,数据库中对应的值保持不变。

我尝试修改方法来有条件地构造 SQL 更新查询和值,但我很难让它正确。如何调整该方法,使其仅更新非

None
的参数的数据库值?

python sqlite fastapi
1个回答
0
投票

为了这个答案的目的,我将假设表中存在必要的列(它们可能应该;首先定义列有什么好处吗?)。

如果将列名称放在一个列表中,将参数值放在另一个列表中,则可以并行迭代这两个列表(使用

zip
)以选择要包含在查询中的列/值对。

然后,如有必要,您可以使用

UPDATE
从所选列名称列表中构造
', '.join
命令。

def saveSettings(self, name, font_size=None, bg_color=None, font_color=None, title_header=None, sorting_header=None):
    if not self._taskboard_exists(name):
        raise Exception(f"Taskboard '{name}' does not exist.")

    values = [font_size, bg_color, font_color, title_header, sorting_header]

    # This can be hard-coded outside the function, since it's not
    # going to change.
    names = ['font_size', 'bg_color', 'font_color', 'title_header', 'sorting_header']

    update_columns = []
    update_values = []

    for column, value in zip(names, values):
        if value is not None:
            update_columns.append(f"{column} = ?")
            update_values.append(value)

    if not update_values:
        return  # Nothing to do

    with self.global_db:
        cursor = self.global_db.cursor()
        cursor.execute(
            f"UPDATE '{name}' SET " + ', '.join(update_columns),
            update_values
        )
        self.global_db.commit()

此外,请考虑使用类似

sqlalchemy.sql
的内容来避免像这样手动构建 SQL。

© www.soinside.com 2019 - 2024. All rights reserved.