Не могу сделать sql запрос с внутренней переменной python
def data_print(self):
return{
"exams_id1": self.ui.cmbBoxFirstExam.currentData().id,
"exam_id2": self.ui.cmbBoxSecondExam.currentData().id,
"exam_id3": self.ui.cmbBoxThirdExam.currentData().id,
"degrees_id": self.ui.cmbBoxQualif.currentData().id,
"educationform_id":self.ui.cmbBoxFormEduc.currentData().id
}
def onBtnAccClick(self):
data = MainWindow.data_print(self)
with Session(self.engine) as s:
query = """
SELECT direction, profile,budget,commerce,min
FROM directions
WHERE d_id = %(degress_id)s
"""
rows = s.execute(text(query))
for r in rows:
item = QListWidgetItem()
item.setData(QtCore.Qt.ItemDataRole.UserRole, r)
self.ui.listWidget.addItem(item)
это кусок кода. Вся суть в том, что мне нужно сравнить d_id(переменная хранится в базе данных directions) с переменной которую я извлекаю из combobox. Но при выполнении кода в консоль выходит следующая ошибка:
sqlalchemy.exc.StatementError: (builtins.KeyError) 'degress_id'
[SQL:
SELECT direction, profile,budget,commerce,min
FROM directions
WHERE d_id = ?
]
[parameters: [{}]]
Ответы (1 шт):
Первое: Вы создали соединение с базой данных с помощью контекстного менеджера with Session(self.session) as s:
, но при этом обращаетесь к соединению s
уже вне блока with
Правильный вариант выглядит так:
query = """
SELECT direction, profile,budget,commerce,min
FROM directions
WHERE d_id = %(degress_id)s
"""
with Session(self.engine) as s:
rows = s.execute(text(query)) # Обращение к соединению происходит внутри контекстного менеджера
По поводу вставки переменных в запрос, приведу маленький пример:
query = text("""
SELECT direction, profile,budget,commerce,min
FROM directions
WHERE d_id= :degress_id
""")
with Session(self.engine) as s:
rows = s.execute(query, {"degress_id": 3})
В этом примере: для безопасной вставки переменных я использую не встроенный в python метод format
. Это не безопасно! Можно будет легко провести атаку XSS потому что не происходит экранирования.
Вы используете sqlalchemy
, а он предоставляет собственный функционал подставления переменных в сырой запрос, а именно вы указываете переменную с помощью имени и символа :
перед ней, и уже перед самим выполнением передаете dict
пар "переменная": значение. И сам sqlalchemy
за Вас проделает оставшуюся работу.
Готов ответить на вопросы, если они возникнут.