На этом шаге мы рассмотрим основные конструкции, используемые для взаимодействия с такой базой данных.
Вам нужно выбирать, вставлять или удалять строки в реляционной базе данных.
Стандартный способ представления строк данных в Python - это последовательность кортежей. Например:
stocks = [ ('GOOG', 100, 490.1), ('AAPL', 50, 545.75), ('FB', 150, 7.45), ('HPQ', 75, 33.2), ]
Если данные представлены в такой форме, относительно легко наладить взаимодействие с реляционной базой данных, используя стандартный API баз данных Python, как описано в PEP 249.
https://peps.python.org/pep-0249/.
Суть API в том, что все операции с базой данных выполняются с помощью SQL-запросов. Каждая строка вводимых или выводимых данных представлена в форме кортежа.
Чтобы попробовать это в деле, вы можете воспользоваться модулем sqlite3, который входит в стандартную поставку Python. Если вы используете другую базу данных (например, MySQL, Postgres, ODBC), вы должны будете установить стороннюю библиотеку. Однако программный интерфейс будет практически таким же, если не идентичным.
Первый шаг - подсоединиться к базе данных. Обычно для этого нужно вызвать функцию connect() и передать ей такие параметры, как имя базы данных, имя хоста, имя пользователя, пароль и другие детали, по мере необходимости. Например:
>>> import sqlite3 >>> db = sqlite3.connect('database.db') >>>
Чтобы что-то делать с данными, нужно создать курсор. Когда у вас есть курсор, вы можете выполнять SQL-запросы. Например:
>>> c = db.cursor() >>> c.execute('create table portfolio (symbol text, shares integer, price real)') <sqlite3.Cursor object at 0x00000264BFA6F490> >>> db.commit() >>>
Чтобы вставить последовательность строк в данные, используйте такую инструкцию:
>>> c.executemany('insert into portfolio values (?,?,?)', stocks) <sqlite3.Cursor object at 0x00000264BFA6F490> >>> db.commit() >>>
Чтобы сделать запрос, используйте такую инструкцию:
>>> for row in db.execute('select * from portfolio'): print(row) ('GOOG', 100, 490.1) ('AAPL', 50, 545.75) ('FB', 150, 7.45) ('HPQ', 75, 33.2) >>>
Если вы хотите сделать запросы, которые принимают поставляемые пользователем входные параметры, убедитесь, что вы экранируете параметры, используя символ ?:
>>> min_price = 100 >>> for row in db.execute('select * from portfolio where price >= ?', (min_price,)): print(row) ('GOOG', 100, 490.1) ('AAPL', 50, 545.75) >>>
На низком уровне взаимодействие с базой данных выполняется абсолютно прямолинейно. Вы просто формируете SQL-запросы и передаете их модулю, чтобы либо обновить информацию в базе, либо извлечь данные. Тем не менее есть тонкие моменты, с которыми в некоторых случаях придется разбираться.
Одно из возможных осложнений - отображение данных из базы на типы Python. Для записей типа дат наиболее частым случаем будет использование экземпляров datetime из одноименного модуля или системных временных меток (timestamps) с применением модуля time. Для числовых данных, и особенно финансовых данных, в которых применяются десятичные дроби, может применяться представление чисел как экземпляров Decimal из модуля decimal. К сожалению, конкретные принципы отображения варьируются в зависимости от бэкэнда базы данных, так что вам придется почитать документацию.
Еще одно критически важное осложнение касается формирования строк с инструкциями SQL. Вы никогда не должны использовать операторы форматирования строк Python (например, %) или метод .format() для создания таких строк. Если значения, предоставленные таким операторам форматирования, вводятся пользователями, это открывает вашу программу для SQL-инъекций.
См. https://xkcd.com/327/.
Специальный подменяющий символ ? в запросах требует от бэкэнда базы данных использовать его собственный механизм подстановки строк, который (будем надеяться) делает это безопасно.
К сожалению, существует некоторое разнообразие в том, как бэкэнды различных баз данных интерпретируют символы подстановки. Многие модули используют ? или %s, тогда как другие могут использовать иной символ, такой как :0 или :1, чтобы ссылаться на параметры. Вам нужно обратиться к документации используемого модуля базы данных. Атрибут paramstyle модуля базы данных также содержит информацию о стиле использования кавычек.
Для простого взаимодействия с таблицей базы данных использовать API обычно очень просто. Если вы делаете что-то более нетривиальное, имеет смысл использовать высокоуровневый интерфейс, такой как объектно-реляционные отображатели (ORM). Библиотеки типа SQLAlchemy позволяют описывать таблицы базы данных как классы Python и выполнять операции с базами данных, скрывая весь лежащий в основе SQL.
https://www.sqlalchemy.org/.
На следующем шаге мы рассмотрим декодирование и кодирование шестнадцатеричных цифр.