Я не программист на Python, но я давно занимаюсь SQL.Я даже написал свой собственный ORM.Мой совет: не пишите свой собственный конструктор запросов SQL.Существует множество тонких проблем, особенно проблем безопасности.Ниже я подробно остановлюсь на некоторых из них.
Вместо этого используйте хорошо известный SQL Query Builder или ORM.Они уже занимались этими вопросами.Вот пример использования SQLAlchemy .
from datetime import date
from sqlalchemy import create_engine, MetaData
# Connect to the database with debugging on.
engine = create_engine('sqlite:///test.sqlite', echo=True)
conn = engine.connect()
# Read the schemas from the database
meta = MetaData()
meta.reflect(bind=engine)
# INSERT INTO users (name, birthday, state, country) VALUES (?, ?, ?, ?)
users = meta.tables['users']
conn.execute(
users.insert().values(name="Yarrow Hock", birthday=date(1977, 1, 23), state="NY", country="US")
)
SQLAlchemy может выполнять весь диапазон операций SQL и будет работать с различными вариантами SQL.Вы также получаете тип безопасности.
conn.execute(
users.insert().values(name="Yarrow Hock", birthday="in the past", state="NY", country="US")
)
sqlalchemy.exc.StatementError: (exceptions.TypeError) SQLite Date type only accepts Python date objects as input. [SQL: u'INSERT INTO users (name, birthday, state, country) VALUES (?, ?, ?, ?)']
insert into table values (...)
зависит от порядка определения столбцов
Это зависит от порядка столбцов, определенных в схеме.Это оставляет две проблемы.Во-первых, это проблема читабельности.
add2Db(db, 'some_table', (1, 39, 99, 45, 'papa foxtrot', 0, 42, 0, 6)
Что это значит?Читатель не может сказать.Они должны копаться в схеме и подсчитывать столбцы, чтобы выяснить, что означает каждое значение.
Во-вторых, это проблема технического обслуживания.Если по какой-либо причине схема изменяется и порядок столбцов не является точно одинаковым, это может привести к чрезвычайно трудным поискам ошибок.Например ...
create table users ( name text, birthday date, state text, country text );
vs
create table users ( name text, birthday date, country text, state text );
add2Db(db, 'users', ('Yarrow Hock', date(1977, 1, 23), 'NY', 'US'));
Эта вставка будет молча "работать" с любым порядком столбцов.
Это можно исправить, передав словарь и используя ключи для имен столбцов.
add2Db(db, 'users', (name="Yarrow Hock", birthday=date(1977, 1, 23), state="NY", country="US"));
Затем мы создадим запрос, подобный следующему:
insert into users
(name, birthday, state, country)
values (?, ?, ?, ?)
Это приводит к следующей и гораздо более серьезной проблеме.
Атака SQL-инъекцией
Теперь это открывает новую проблему.Если мы просто вставим имена таблиц и столбцов в запрос, который оставляет нас открытыми для одной из самых распространенных дыр в безопасности, SQL Injection Attack .Вот где кто-то может создать значение, которое при наивном использовании в выражении SQL заставляет запрос делать что-то еще.Как Маленькие таблицы Бобби .
Хотя ?
защищает от SQL-инъекций для значений, все еще возможно вводить через имена столбцов.Там нет гарантии, что имена столбцов можно доверять.Может быть, они пришли из параметров веб-формы?
Защита имен таблиц и столбцов сложна и легко ошибиться.
Чем большеSQL вы пишете, тем более вероятно, что вы уязвимы для инъекционной атаки.
Вы должны написать код для всего остального.
Хорошо, вы сделали insert
.Сейчас update
?select
?Не забывайте о подзапросах, группировании, объединениях, объединениях ...
Если вы хотите написать конструктор SQL-запросов, круто!Если вместо этого у вас есть работа с использованием SQL, написание еще одного компоновщика SQL-запросов не ваша работа.
Труднее понять другим.
Есть хороший шанс, что любойданный программист на Python знает, как работает SQLAlchemy, и есть множество руководств и документации, если они этого не делают.У них нет шансов узнать о ваших собственных функциях SQL, и вы должны написать все учебные пособия и документы.