Как безопасно параметризовать идентификаторы pyodb c в запросах? - PullRequest
0 голосов
/ 18 февраля 2020

Я написал небольшой инструмент, который переносит данные с SQL Сервера на 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()
...

Это выглядит довольно безопасно, но также не делает Работа. Появляется следующая ошибка:

pyodb c .ProgrammingError: ('42000', '[42000] [Microsoft] [ODB C SQL Драйвер сервера] [SQL Сервер] D ie @ P1-Tabellenvariable muss deklariert werden. (1087) (SQLExecDirectW); [42000] [Microsoft] [ODB C SQL Драйвер сервера] [SQL Сервер] Anweisung (en) konnte (n) nicht vorbereitet werden. (8180) ')

Это на немецком языке, но примерно переводится как: переменные таблицы должны быть объявлены, оператор не может быть подготовлен.

Как передать переменную в метод execute для безопасного размещения идентификаторов?

1 Ответ

0 голосов
/ 18 февраля 2020

Вы не можете иметь переменную для имени таблицы в SQL Server. Вы можете сгенерировать строку в python и затем выполнить ее.

table_name = 'table1' 
query = "Select * from %s" % table_name

Или вы можете использовать Dynami c SQL.

...