Я написал небольшой инструмент, который переносит данные с SQL Server на Postgres.
Чтобы все заработало, я сделал это быстро и грязно, используя конкатенацию строк, поскольку мне нужно было решить множество других проблем, и в то время я не хотел возиться с SQL. Но теперь, когда все разобралось, я хочу делать все правильно в отделе SQL.
Небезопасная быстрая и грязная версия:
import pyodbc
# this is the bad example DON'T do this
def getDataFromTable(self,table):
"""
Gets all data from the specified Table.
table -- Table name as string
"""
cursor = self.cursor
SQL = f"""SELECT * FROM {table}""" ## DON'T do this
cursor.execute(SQL)
rows = cursor.fetchall()
records = []
for row in rows:
records.append(list(row))
return records
Это работает отлично, но ожидает SQL-инъекция.
Я хочу построить что-то вроде этого (я пропустил неизменные части):
...
cursor = self.cursor
SQL = f"""SELECT * FROM ?""" # Use parameters insted of string concats
cursor.execute(SQL, table) # pass parameters to the execute method.
rows = cursor.fetchall()
...
Сейф выглядит неплохо, но тоже не работает. Выскакивает следующая ошибка:
pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Die @ P1-Tabellenvariable muss deklariert werden. (1087) (SQLExecDirectW); [42000] [Microsoft] [ODBC Драйвер SQL Server] [SQL Server] Anweisung (en) konnte (n) nicht vorbereitet werden. (8180) ')
Это на немецком языке, но примерно переводится как: переменные таблицы должны быть объявлены, оператор не может быть подготовлен.
Как я могу передать переменную в метод execute, чтобы безопасно разместить идентификаторы?