簡體   English   中英

Python Sqlite3數據庫表未更新

[英]Python Sqlite3 Database table isn't being updated

我正在為網站創建一個更改密碼頁面,該頁面要求新密碼和當前密碼。 使用scrypt庫對舊密碼進行哈希處理和加鹽處理,然后將其與sqlite3數據庫中存儲的密碼進行比較,如果匹配,則對新密碼進行哈希處理並更新數據庫。 但是我在執行更新命令時遇到了困難,因為它引發了sqlite3.OperationalError:無法識別的令牌:“ \\”錯誤。 execute語句當前具有以下代碼:

c.execute("UPDATE users SET password = \'{0}\' WHERE memberID = \'{1}\'".format(newPas, memID))

最初,我們認為該錯誤是由於在新密碼本身中由於存在'而在字符串格式中使用'引起的,因此再次將其運行為:

c.execute("UPDATE users SET password = \"{0}\" WHERE memberID = \"{1}\"".format(newPas, memID))

這可以成功運行,但實際上不會更改數據庫中的任何內容。 我們還嘗試創建一個查詢字符串,然后執行該字符串。

query = "UPDATE users SET password = {0} WHERE memberID = {1}".format(newPas, memID)
c.execute(query)

這導致了sqlite3.OperationalError:“'\\ xa1 \\ x91 \\ x9f \\ x88 \\ xfb \\ x81 \\ x12 \\ xd4 \\ xc2 \\ xf9 \\ xce \\ x91y \\ xf0 / \\ xe1 *#\\ x8aj \\ xc7 \\ x1d \\ xd3 \\ x91 \\ x14 \\ xcb \\ xa4 \\ xabaP [\\ x02 \\ x1d \\ x1b \\ xabr \\ xc7 \\ xe4 \\ xee \\ x19 \\ x80c \\ x8e | \\ xc0S \\ xaaX \\ xc6 \\ x04 \\ xab \\ x08 \\ x9b \\ x8e \\ xd7zB \\ xc6 \\ x84 [\\ xfb \\ xbc \\ x8d \\ xfc'“:語法錯誤。 我相信這是由於密碼中存在'和'字符引起的,但是我不確定如何解決此問題,因為這些是由哈希過程添加的,因此刪除它們會更改密碼。我想輸入密碼要添加的是:

b'\xa1\x91\x9f\x88\xfb\x81\x12\xd4\xc2\xf9\xce\x91y\xf0/\xe1*#\x8aj\xc7\x1d\xd3\x91\x14\xcb\xa4\xabaP[\x02\x1d\x1b\xabr\xc7\xe4\xee\x19\x80c\x8e|\xc0S\xaaX\xc6\x04\xab\x08\x9b\x8e\xd7zB\xc6\x84[\xfb\xbc\x8d\xfc'

我想知道是否有人可以分享一些為什么它不喜歡“ \\”字符或為什么它不更新數據庫的見解,並指出正確的方向來使其工作。 如果您需要更多信息或代碼段,或者只是想對我大吼大叫,請不要猶豫! 先感謝您 :)

您應該使用參數化查詢,如下所示:

c.execute(“”“”更新用戶SET密碼=?WHERE成員ID =?;“”,(newPas,memID))

這樣可以避免出現諸如SQL注入之類的令人討厭的事情。

您的代碼有兩件事:

  1. 您不應該使用format來構建這樣的查詢。 這使您易於進行SQL注入,盡管在這種情況下您可能需要清理輸入,但這是一個會咬傷您的壞習慣。
  2. 所有更改都必須提交到數據庫才能真正生效。 這就是為什么第二個查詢沒有引發錯誤,但是同樣沒有對數據庫進行任何更改的原因。

該查詢的正確格式為:

conn = sqlite3.connect('my_db.db')
c = conn.cursor()

query = "UPDATE users SET password = ? WHERE memberID = ?"
c.execute(query, (newPas, memID))

conn.commit() # To finalise the alteration

附帶說明一下,在這種情況下,游標需要一個元組,因此在傳遞單個值時會遇到一個常見的絆腳石:

query = "UPDATE users SET password = ? WHERE memberID = 'abc'"
c.execute(query, (newPas)) # Throws "incorrect number of bindings" error

# Use this instead i.e. pass single value as a tuple
c.execute(query, (newPas,))

您可以使用format在查詢中創建變量字段名稱,因為在這種情況下不允許使用占位符:

fields = ['a', 'b', 'c']

query = "UPDATE users SET {} = ?".format(random.choice(fields))

除了使用它來幫助您構建大型查詢之外,在這些查詢中手動鍵入所有占位符會很繁瑣,並且如果代碼更改,則很難確保您擁有正確的數字:

my_list = ['a', 'b',...., n]
placeholders = ', '.join(['?' for item in my_list])

query = "INSERT .... VALUES = ({})".format(placeholders)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM