我正在使用flask-restful,用戶可以發布一些必需的和一些可選的資料,我想用這些資料制作一個SQLite插入陳述句。問題是我不想通過使用列名的變數并檢查哪個引數是哪個引數None以及哪個有一些資料來破壞 sql 陳述句。我希望我可以只使用所有列,當 arg2 或 arg3 是None時,資料庫將使用列默認值。可悲的是我得到了訊息NOT NULL constraint failed: mytable.col1。使用我的方法從表創建中洗掉NOT NULL只會在使用我的陳述句時插入 NULL。
有沒有明確的方法告訴 SQLite 使用它的默認值?
如果沒有,是否有更優雅的方式來獲取默認值而不是執行某些表模式查詢?
如果沒有并且不存在其他解決方案,那么屠宰 sql 陳述句的最有效方法是什么?
parser_post = reqparse.RequestParser()
parser_post.add_argument('arg1', type=str, required=True)
parser_post.add_argument('arg2', type=str)
parser_post.add_argument('arg3', type=str)
args = parser_post.parse_args()
# ... db init code
cur.execute("insert into mytable (col1, col2, col3) values (?, ?, ?)",
(args['arg1'], args['arg2'], args['arg3']))
該表是這樣創建的:
sql = """CREATE TABLE mytable (
PK_id INTEGER PRIMARY KEY AUTOINCREMENT,
col1 INTEGER NOT NULL,
col2 TEXT DEFAULT "global" NOT NULL,
col3 TEXT DEFAULT "global" NOT NULL)"""
cursor.execute(sql)
uj5u.com熱心網友回復:
回退到資料庫端默認值的一種方法是不為插入中的特定列提供資料。
在這種情況下,服務器將為該列插入默認值。如果您沒有在CREATE TABLE(或以后的 ALTER TABLEs)中指定默認值,則默認值為 NULL(對應于 Python None)。
但是,由于 col2確實具有資料庫指定的默認值 via col2 TEXT DEFAULT "global" NOT NULL,因此在插入中未指定col2將導致 sqlite 使用"global". 同上col3。
您可以動態構建查詢,以排除帶有 的列None,只要您對查詢字串中的內容保持謹慎。
def prep_qry(args, colnames):
"""this query is secure as long as `colnames` contains trusted data
standard parametrized query mechanism secures `args`"""
binds,use = [],[]
for colname, value in zip(colnames,args):
if value is not None:
use.extend([colname,","])
binds.extend(["?",","])
parts = ["insert into mytable ("]
use = use[:-1]
binds = binds[:-1]
parts.extend(use)
parts.append(") values(")
parts.extend(binds)
parts.append(")")
qry = " ".join(parts)
return qry, tuple([v for v in args if not v is None])
print(prep_qry([1,None,3], ["col1", "col2", "col3"]))
print(prep_qry([1,2,3], ["col1", "col2", "col3"]))
輸出:
('insert into mytable ( col1 , col3 ) values( ? , ? )', (1, 3))
('insert into mytable ( col1 , col2 , col3 ) values( ? , ? , ? )', (1, 2, 3))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/414578.html
標籤:
