Я реализую класс онтологии Python, который использует бэкэнд базы данных для хранения и запроса онтологии. Схема базы данных фиксирована (заранее задана), но я не знаю, какой тип механизма базы данных используется. Однако я могу положиться на то, что интерфейс Python для механизма базы данных использует Python DB-API 2.0 (PEP 249). Прямая идея состоит в том, чтобы позволить пользователю передать PEP 249-совместимый объект Connection
конструктору моей онтологии, который затем будет использовать различные запрошенные SQL-запросы с жесткой кодировкой для запроса базы данных:
class Ontology(object):
def __init__(self, connection):
self.connection = connection
def get_term(self, term_id):
cursor = self.connection.cursor()
query = "SELECT * FROM term WHERE id = %s"
cursor.execute(query, (term_id, ))
[...]
Моя проблема заключается в том, что различным бэкендам базы данных разрешено поддерживать разные маркеры параметров в запросах, определенных атрибутом paramstyle
бэкэнд-модуля. Например, если paramstyle = 'qmark'
, интерфейс поддерживает стиль вопросительного знака (SELECT * FROM term WHERE id = ?
); paramstyle = 'numeric'
означает числовой, позиционный стиль (SELECT * FROM term WHERE id = :1
); paramstyle = 'format'
означает стиль строки формата ANSI C (SELECT * FROM term WHERE id = %s
). Если я хочу, чтобы мой класс мог обрабатывать различные базы данных, мне кажется, что я должен подготовиться ко всем стилям маркеров параметров. Это, похоже, превзошло всю цель общего API БД для меня, поскольку я не могу использовать тот же параметризованный запрос с различными базами данных базы данных.
Есть ли способ обойти это, и если да, то какой лучший подход? API БД не указывает на существование общей функции экранирования, с помощью которой я могу дезинфицировать мои значения в запросе, поэтому выполнение экранирования вручную не является вариантом. Я не хочу добавлять дополнительную зависимость к проекту, используя еще более высокий уровень абстракции (например, SQLAlchemy).