development

SQLite 매개 변수 대체 문제

big-blog 2020. 12. 27. 20:40
반응형

SQLite 매개 변수 대체 문제


Python 2.5에서 SQLite3를 사용하여 목록을 반복하고 항목 이름을 기반으로 데이터베이스에서 항목의 가중치를 가져 오려고합니다.

"?"를 사용해 보았습니다. SQL 주입을 방지하기 위해 제안 된 매개 변수 대체가 작동하지 않습니다. 예를 들어 다음을 사용할 때 :

for item in self.inventory_names:
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", item)
    self.cursor.close()

오류가 발생합니다.

sqlite3.ProgrammingError : 잘못된 바인딩 수가 제공되었습니다. 현재 명령문은 1을 사용하고 8 개가 제공됩니다.

나는 이것이 어떻게 든 데이터베이스의 초기 생성으로 인한 것이라고 생각합니다. 실제로 DB를 생성하는 모듈에는 8 개의 바인딩이 있습니다.

cursor.execute("""CREATE TABLE Equipment 
    (id INTEGER PRIMARY KEY, 
    name TEXT,
    price INTEGER, 
    weight REAL, 
    info TEXT, 
    ammo_cap INTEGER, 
    availability_west TEXT,
    availability_east TEXT)""")

그러나 각 항목 이름에 대해 덜 안전한 "% s"대체를 사용하면 제대로 작동합니다. 이렇게 :

for item in self.inventory_names:
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = '%s'" % item)
    self.cursor.close()

하나만 호출 할 때 8 개의 bindin이 있다고 생각하는 이유를 알 수 없습니다. 어떻게 고칠 수 있습니까?


Cursor.execute()메서드는 두 번째 매개 변수로 시퀀스를 예상합니다. 8 자 길이의 문자열을 제공하고 있습니다.

대신 다음 양식을 사용하십시오.

self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", [item])

Python 라이브러리 참조 : sqlite3 Cursor Objects .


나는 왜 이런 일이 나에게 오류를 일으키는 지 알아 내려고 반나절을 보냈습니다.

cursor.execute("SELECT * from ? WHERE name = ?", (table_name, name))

테이블 이름 을 매개 변수화 할 수 없다는 것을 알아 내기 위해서입니다 . 이것이 다른 사람들이 시간을 절약하는 데 도움이되기를 바랍니다.


cursor.execute데이터베이스에 삽입해야하는 값을 나타내는 인수는 튜플 (시퀀스)이어야합니다. 그러나이 예를 고려하고 무슨 일이 일어나고 있는지 확인하십시오.

>>> ('jason')
'jason'

>>> ('jason',)
('jason',)

첫 번째 예제는 대신 문자열로 평가됩니다. 따라서 단일 값 튜플을 나타내는 올바른 방법은 두 번째 평가에서와 같습니다. 어쨌든 아래 코드는 오류를 수정합니다.

self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item,))

또한 cursor.execute값 인수를 문자열로 제공하면 (당신이하는 일입니다) 예제에서 첫 번째 평가가 발생하고 오류가 발생합니다.


이것을 시도해 보셨습니까? :

for item in self.inventory_names:
    t = (item,)
    self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", t)
    self.cursor.close()

cursor.execute ()는 두 번째 매개 변수로 시퀀스 (list, tuple)를 예상합니다. (-> ddaa)


인용 (괄호가 의미하는 것은 무엇입니까?)? 괄호로 나를 위해 일하는 것 같습니다. (문자 그대로) '?' 하지만 계속

ProgrammingError : 잘못된 수의 바인딩이 제공되었습니다. 현재 명령문은 0을 사용하고 1이 제공됩니다.

내가했을 때 :

팩 토이 드에서 팩트 선택 WHERE key LIKE (?)

대신에:

팩 토이 드에서 팩트 선택 WHERE key LIKE '?'

효과가있었습니다.

이것은 파이썬 2.6 일입니까?


항목의 각 요소는 튜플이어야합니다. 이름이 다음과 같다고 가정합니다.

names = ['Joe', 'Bob', 'Mary']

다음을 수행해야합니다.

for item in self.inventory_names:
self.cursor.execute("SELECT weight FROM Equipment WHERE name = ?", (item, ))

by using (item, ) you are making it a tuple instead of a string.


The sqlite3 module supports two kinds of placeholders for parameters:

qmark style

Use one or more ? to mark the position of each parameter, and supply a list or tuple of parameters. E.g.:

curs.execute("SELECT weight FROM Equipment WHERE name = ? AND price = ?",
             ['lead', 24])

named style

Use :par placeholders for each named parameter, and supply a dict. E.g.:

curs.execute("SELECT weight FROM Equipment WHERE name = :name AND price = :price",
             {name: 'lead', price: 24})

Advantages of named style parameters is that you don't need to worry about the order of parameters, and each :par can be used multiple times in large/complex SQL queries.


Try

execute("select fact from factoids where key like ?", "%%s%" % val)

You don't wrap anything around the ? at all, Python sqlite will correctly convert it into a quoted entity.

ReferenceURL : https://stackoverflow.com/questions/228912/sqlite-parameter-substitution-problem

반응형