【问题标题】:Skip None values in entry widgets Tkinter Python在条目小部件 Tkinter Python 中跳过无值
【发布时间】:2021-07-03 07:44:46
【问题描述】:

假设我们有一个 Tkinter 应用程序,其中包含许多这样的入口小部件:

root = Tk()

entry1 = Entry(root, width=40)
entry1.grid(row=0, column=0)
entry2 = Entry(root, width=40)
enrtry2.grid(row=1,column=0)
entry3 = Entry(root, width=40)
enrtry3.grid(row=2,column=0)
entry4 = Entry(root, width=40)
enrtry4.grid(row=3,column=0)

root.mainloop()

来自这些小部件的值用于UPDATE 数据库。我想要的是能够跳过其中任何一个值,而不是在UPDATE 语句中使用它。现在我用我的代码检查小部件中是否写了这样的东西:

db = fdb.connector
c = db.cursor

values = [entry1.get(), entry2.get(), entry3.get(), entry4.get()]

for v in values:
   if len(v) == 0 or v is None:
     pass
   elif lev(v) != 0:
     c.execute(f"""UPDATE table1 SET column1 = {v[0]}, column2 = {v[1]}, column3 = {v[2]}, column4 = {v[3]} WHERE ID = 1;""")

问题是当数据库中的值之一是None 时,我得到的值是NULL,这是正确的,因为widget 中没有值。我如何“告诉”python,当没有提供值时,它应该跳过该值并继续更新其他值?

编辑:感谢@TheLizzard,这个解决方案就像一个魅力:

string = "UPDATE table1 SET "
        at_least_one_set = False
        for i in range(12):
             if v[i] != "":
                 string += columns[i] + " = " + "'" + str(v[i]) + "'" + ", "
                 at_least_one_set = True
        if at_least_one_set:
            string = string[:-2]
            string += f" WHERE column_a = '{v[0]}' OR column_b = '{v[1]}';"
            c.execute(string)
        else:
            print("No values were set. Raise an error?")

EDIT2: 经过一番研究,感谢@TheLizzard、@Arioch 'The、@Mark Rotteveel,我提供了以下工作代码并遵循here 的建议之一现在是安全的:

v = ["", "2", "3", ""]
column_names = ["column_a", "column_b", "column_c", "column_z"]
rowids = [row[0] for row in c.execute("SELECT id FROM table1 WHERE column_a = ? OR column_b = ?", (v[0], v[1], ))]

string = "UPDATE table1 SET "
at_least_one_set = False
for i in range(12):
    if v[i] != "":
        string += columns[i] + " = '{}'".format(v[i]) + ", "
        at_least_one_set = True
if at_least_one_set:
   string = string[:-2]
   string += " WHERE id = {}".format(rowids[0]) + ";"
   c.execute(string)

结果是:

UPDATE table1 SET column_b = '2', column_c = '3' WHERE id = 1;

【问题讨论】:

  • 所以你想把v = ["", "b", "c", ""] 转换成"UPDATE table1 SET column2 = b, column3 = c;" 对吧?
  • 是的,这正是我想要的。
  • 您当前的工作方式容易受到 SQL 注入的攻击。
  • 不带 WHERE 子句的更新表将更新表中的所有记录。真的是你想要的吗?
  • @MarkRotteveel 这个:c.execute(f"""UPDATE table1 SET column1 = ?, column2 = ?, column3 = ?, column4 = ?;""", (v[0],v[1],v[2],v[3])) 是我解决问题后的方式。 @acw1668 不,我将添加WHEREID 列,该列存在于表中并且是其主键。但我又一次在表中得到了我不想要的 None 值。

标签: python sql tkinter firebird


【解决方案1】:

试试这个:

v = ["", "2", "3", ""]
column_names = ["column_a", "column_b", "column_c", "column_z"]


string = "UPDATE table1 SET "
at_least_one_set = False
for i in range(4):
    if v[i] != "":
        string += column_names[i] + " = " + v[i] + ", "
        at_least_one_set = True
if at_least_one_set:
    string = string[:-2]
    string += ";"
    print(string)
else:
    print("No values were set. Raise an error?")

我动态创建了一个以"UPDATE table1 SET " 开头并以";" 结尾的字符串,我跳过了所有"" 的值。

【讨论】:

  • 这看起来不错,但是如果列的名称不同怎么办?
  • @T0ny1234 完成。再试一次,如果您需要更多改进,请告诉我。
  • 谢谢,这真是天才。我会尝试更新问题。
  • 请注意,此解决方案易受 SQL 注入攻击
  • @MarkRotteveel 忘记了 SQL 注入。我仍然不明白大部分 SQL 是如何工作的。如果你知道如何解决这个问题,你可以编辑我的答案:D。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多