Executescript python что это
Методы объекта Cursor SQLite3.
Синтаксис:
В разделе рассмотрены методы объекта Cursor модуля sqlite3 с подробным описанием и примерами.
Содержание:
A Cursor instance has the following attributes and methods.
cursor.execute(sql[, parameters]) :
Метод cursor.execute() выполняет команду SQL. Команды SQL могут быть параметризованными, то есть передаются заполнители вместо литералов SQL.
Пример использования обоих стилей:
cursor.executemany(sql, seq_of_parameters) :
Модуль sqlite3 также позволяет использовать итератор, который выдает параметры.
cursor.executescript(sql_script) :
cursor.fetchone() :
cursor.fetchmany(size=cursor.arraysize) :
cursor.fetchall() :
Метод cursor.fetchall() выбирает все оставшиеся строки результата запроса, возвращая список.
Обратите внимание, что атрибут cursor.arraysize() курсора может повлиять на производительность этой операции. Метод возвращает пустой список, когда нет доступных строк.
cursor.close() :
cursor.rowcount :
cursor.lastrowid :
Атрибут cursor.lastrowid только для чтения, предоставляет идентификатор последней измененной строки в базе данных.
Атрибут cursor.lastrowid будет возвращен, если оператору INSERT или REPLACE не удалось успешно вставить предыдущий идентификатор строки.
cursor.arraysize :
Значение по умолчанию равно 1, что означает, что для каждого вызова будет выбрана одна строка.
cursor.description :
Он также устанавливается для операторов SELECT без соответствующих строк.
Методы execute, executemany, executescript, commit, rollback
На предыдущих занятиях мы с вами рассмотрели основы языка SQL для взаимодействия с СУБД SQLite. Теперь поговорим о методах пакета sqlite3, то есть, об API данной СУБД. Некоторые моменты мы уже затрагивали и отмечали, что для базовой работы с БД можно использовать менеджер контекста:
Это необходимые действия для сохранения внесенных изменений в БД.
Методы execute, executemany и executescript
Давайте добавим в таблицу cars несколько записей. В самом простом случае это можно сделать так:
В результате, таблица будет содержать данные:
Однако, когда мы программируем на Python, то данные, как правило, хранятся в каких-либо коллекциях, например, так:
И мы бы хотели брать значения из этого списка и передавать их в SQL-запрос. Для этого запрос следует записывать в виде следующего шаблона:
Здесь вместо знаков вопроса будут подставлены соответствующие данные из первого кортежа списка. Соответственно, весь набор ранее приведенных строчек, можно заменить циклом:
Или, еще проще, воспользоваться методом executemany, который специально для этого и существует:
Сразу же здесь отмечу, что помимо знаков вопроса можно использовать именованные параметры (плейсхолдеры). Для этого в запросе перед ними ставится двоеточие, а затем, указывается словарь, где имя – это ключ, вместо которого будет подставлено его значение:
Далее, если нужно выполнить несколько отдельных SQL-команд, то можно передать их СУБД с помощью метода executescript:
Мы здесь сначала удаляем все записи, у которых модель начинается на букву A, а затем у оставшихся записей увеличиваем цену на 1000. Причем, команды должны отделяться друг от друга точкой с запятой.
У этого метода есть одно ограничение: здесь нельзя использовать шаблоны запросов, как мы это делали в предыдущих методах. В executescript буквально записываются SQL-запросы как есть со всеми данными.
Методы commit и rollback
Давайте теперь реализуем соединение с БД через блок обработки исключений try/except/finally:
В чем преимущество такого подхода? Смотрите, мы здесь сами «вручную» вызываем методы commit и close. Если операции с таблицами прошли успешно, то они будут сохранены, если же возникли какие-либо ошибки (исключения), то будет вызван метод rollback, который откатывает состояние БД в состояние отметки BEGIN, то есть, все внесенные изменения применены не будут.
Например, укажем в команде UDPATE неверное имя таблицы:
При запуске программы произойдет ошибка выполнения запроса и состояние БД не изменится, то есть, все новые добавленные записи не появятся в таблице cars. А вот если вместо rollback указать commit, то увидим добавление записей. То есть, при использовании менеджера контекста в данном случае не выполнилась бы только последняя команда, но отката состояния БД не произошло бы. Вот так более тонко можно управлять состоянием таблиц в БД.
Если при работе с БД предполагается сохранять вносимые изменения сразу после выполнения SQL-запроса, то это можно сделать с помощью метода connect, установив в нем параметр isolation_level=None:
Однако так делать без особой надобности не стоит, т.к. это уменьшает скорость работы с БД из-за постоянной записи данных непосредственно в файл. Без изменения этого параметра все изменения сохраняются в памяти, а потому работа происходит куда быстрее.
Свойство lastrowid
Давайте теперь представим, что у нас есть еще одна таблица cust, которая содержит покупателей машин. Причем, если происходит покупка по «trade-in», то прежняя машина владельца добавляется в конец таблицы cars, а в таблице cust появляется запись с именем покупателя, идентификатором машины сданной в «trade-in» и id новой купленной машины:
Чтобы реализовать SQL-запрос добавления записи в таблицу cust, нам нужно знать car_id автомобиля сданного в «trade-in». Предположим, что Федор еще не совершил покупку и таблица cars не содержит запись с его сданным автомобилем. Добавим ее. Выполним следующий запрос вот в такой программе:
Мы здесь создаем еще одну таблицу cust с тремя полями и, затем, добавляем в таблицу cars автомобиль «Запорожец», который сдает покупатель Федор. Как теперь нам узнать car_id этой записи? Для этого можно воспользоваться специальным свойством:
которое содержит значение rowid последней добавленной записи. В нашем случае поля car_id и rowid будут совпадать, поэтому воспользуемся этим значением и сформируем еще один запрос на добавление записи во вторую таблицу:
Теперь, при выполнении нашей программы в таблице cust увидим искомую запись. Вот так используется свойство lastrowid.
На этом завершим это занятие. На следующем продолжим рассматривать функционал API для работы с СУБД SQLite.
Видео по теме
Python SQLite #1: что такое СУБД и реляционные БД
Python SQLite #2: подключение к БД, создание и удаление таблиц
Python SQLite #3: команды SELECT и INSERT при работе с таблицами БД
Python SQLite #4: команды UPDATE и DELETE при работе с таблицами
Python SQLite #5: агрегирование и группировка GROUP BY
Python SQLite #6: оператор JOIN для формирования сводного отчета
Python SQLite #7: оператор UNION объединения нескольких таблиц
Python SQLite #8: вложенные SQL-запросы
Python SQLite #9: методы execute, executemany, executescript, commit, rollback и свойство lastrowid
Python SQLite #10: методы fetchall, fetchmany, fetchone, Binary, iterdump
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Методы объекта Connection SQLite3.
Синтаксис:
В разделе рассмотрены методы объекта Connection модуля sqlite3 с подробным описанием и примерами.
Содержание.
Соединение с базой данных SQLite имеет следующие атрибуты и методы:
connect.isolation_level :
Смотрите раздел «Управление транзакциями» для более подробного объяснения.
connect.in_transaction :
Атрибут только для чтения.
connect.cursor(factory=Cursor) :
connect.commit() :
Если встретили ситуацию при которой не видны данные, которые были переданы в базу данных, то необходимо убедится, что метод connect.commit был вызван.
connect.rollback() :
connect.close() :
Метод connect.close() закрывает соединение с базой данных.
connect.execute(sql[, parameters]) :
Пример обоих стилей:
connect.executemany(sql[, seq_of_parameters]) :
connect.executescript(sql_script) :
connect.create_function(name, num_params, func, *, deterministic=False) :
Метод connect.create_function() создает пользовательскую функцию, которую позже можно использовать из операторов SQL под именем функции.
connect.create_aggregate(name, num_params, aggregate_class) :
Метод connect.create_aggregate() создает пользовательскую агрегатную функцию.
connect.create_collation(name, callable) :
Метод connect.create_collation() создает сопоставление с указанным именем name и возможностью вызова.
Вызываемому объекту callable будут переданы два строковых аргумента. Объект callable должен возвращать:
В следующем примере показана пользовательская сортировка.
Можно вызвать этот метод из другого потока, чтобы прервать любые запросы, которые могут выполняться в соединении. Затем запрос будет прерван, и вызывающая сторона получит исключение.
connect.set_authorizer(authorizer_callback) :
Обратный вызов должен возвращать:
connect.set_progress_handler(handler, n) :
Такое поседение полезно, если необходимо получить вызов из SQLite во время длительных операций, например для обновления графического интерфейса. Другими словами позволяет сделать индикатор выполнения PROGRESS BAR
Возврат ненулевого значения из функции-обработчика завершит текущий выполняющийся запрос и вызовет исключение OperationalError.
connect.set_trace_callback(trace_callback) :
Метод connect.set_trace_callback() регистрирует trace_callback для вызова каждого оператора SQL, который фактически выполняется бакэндом SQLite
Передача trace_callback=None отключит обратный вызов трассировки.
connect.enable_load_extension(enabled) :
Метод connect.enable_load_extension() разрешает/запрещает движку SQLite загружать расширения SQLite из общих библиотек. Расширения SQLite могут определять новые функции, агрегаторы или новые реализации виртуальных таблиц. Одним из хорошо известных расширений является расширение полнотекстового поиска (модули FTS3 и FTS4), распространяемое с помощью SQLite.
Загружаемые расширения по умолчанию отключены.
connect.load_extension(path) :
Метод connect.load_extension() загружает расширение SQLite из общей библиотеки.
Загружаемые расширения по умолчанию отключены.
connect.row_factory :
Можно изменить атрибут connect.row_factory на вызываемый объект, который принимает курсор и исходную строку в качестве кортежа и возвращает строку реального результата. Таким образом, можно реализовать более продвинутые способы возврата результатов, например функцию которая может обращаться к столбцам по имени.
connect.text_factory :
Также можно установить для атрибута connect.text_factory любой другой вызываемый объект, который принимает один параметр bytestring и возвращает полученный объект.
Смотрите следующий пример кода для лучшего понимания:
connect.total_changes :
Атрибут connect.total_changes возвращает общее количество строк базы данных, которые были изменены, вставлены или удалены с момента открытия соединения с базой данных.
connect.iterdump() :
Метод connect.iterdump() возвращает итератор для выгрузки базы данных в текстовом формате SQL.
connect.backup(target, *, pages=0, progress=None, name=»main», sleep=0.250) :
По умолчанию или когда pages равно 0 или отрицательному целому числу, вся база данных копируется за один шаг, в противном случае метод выполняет циклическое копирование до страниц pages за один раз.
Аргумент sleep определяет количество секунд, в течение которых происходит переход в спящий режим между последовательными попытками резервного копирования оставшихся страниц и может быть задан либо в виде целого числа, либо в виде значения с плавающей запятой.
Выполнение команд SQL¶
Для выполнения команд SQL в модуле есть несколько методов:
Метод execute¶
Метод execute позволяет выполнить одну команду SQL.
Сначала надо создать соединение и курсор:
Создание таблицы switch с помощью метода execute:
Например, таблицу switch нужно заполнить данными из списка data:
Для этого можно использовать запрос вида:
Знаки вопроса в команде используются для подстановки данных, которые будут передаваться методу execute.
Теперь можно передать данные таким образом:
Чтобы изменения были применены, нужно выполнить commit (обратите внимание, что метод commit вызывается у соединения):
Теперь при запросе из командной строки sqlite3, можно увидеть эти строки в таблице switch:
Метод executemany¶
Метод executemany позволяет выполнить одну команду SQL для последовательности параметров (или для итератора).
С помощью метода executemany в таблицу switch можно добавить аналогичный список данных одной командой.
Например, в таблицу switch надо добавить данные из списка data2:
Для этого нужно использовать аналогичный запрос вида:
Теперь можно передать данные методу executemany:
После выполнения commit данные доступны в таблице:
Метод executemany подставил соответствующие кортежи в команду SQL, и все данные добавились в таблицу.
Метод executescript¶
Метод executescript позволяет выполнить несколько выражений SQL за один раз.
Особенно удобно использовать этот метод при создании таблиц:
Python: Работа с базой данных, часть 1/2: Используем DB-API
В статье рассмотрены основные методы DB-API, позволяющие полноценно работать с базой данных. Полный список можете найти по ссылкам в конец статьи.
Требуемый уровень подготовки: базовое понимание синтаксиса SQL и Python.
Готовим инвентарь для дальнейшей комфортной работы
Примечание: внося изменения в базу не забудьте их применить, так как база с непримененными изменениями остается залоченной.
Вы можете использовать (последние два варианта кросс-платформенные и бесплатные):
Python DB-API модули в зависимости от базы данных
База данных | DB-API модуль |
---|---|
SQLite | sqlite3 |
PostgreSQL | psycopg2 |
MySQL | mysql.connector |
ODBC | pyodbc |
Соединение с базой, получение курсора
Для начала рассмотрим самый базовый шаблон DB-API, который будем использовать во всех дальнейших примерах:
При работе с другими базами данных, используются дополнительные параметры соединения, например для PostrgeSQL:
Чтение из базы
Обратите внимание: После получения результата из курсора, второй раз без повторения самого запроса его получить нельзя — вернется пустой результат!
Запись в базу
Разбиваем запрос на несколько строк в тройных кавычках
Длинные запросы можно разбивать на несколько строк в произвольном порядке, если они заключены в тройные кавычки — одинарные (»’…»’) или двойные («»». «»»)
Конечно в таком простом примере разбивка не имеет смысла, но на сложных длинных запросах она может кардинально повышать читаемость кода.
Объединяем запросы к базе данных в один вызов метода
Данный метод также удобен, когда у нас запросы сохранены в отдельной переменной или даже в файле и нам его надо применить такой запрос к базе.
Делаем подстановку значения в запрос
Важно! Никогда, ни при каких условиях, не используйте конкатенацию строк (+) или интерполяцию параметра в строке (%) для передачи переменных в SQL запрос. Такое формирование запроса, при возможности попадания в него пользовательских данных – это ворота для SQL-инъекций!
Возможны два варианта:
Примечание 1: В PostgreSQL (UPD: и в MySQL) вместо знака ‘?’ для подстановки используется: %s
Примечание 2: Таким способом не получится заменять имена таблиц, одно из возможных решений в таком случае рассматривается тут: stackoverflow.com/questions/3247183/variable-table-name-in-sqlite/3247553#3247553
UPD: Примечание 3: Благодарю Igelko за упоминание параметра paramstyle — он определяет какой именно стиль используется для подстановки переменных в данном модуле.
Вот ссылка с полезным приемом для работы с разными стилями подстановок.
Он всегда возвращает кортеж или None. если запрос пустой.
Курсор как итератор
UPD: Повышаем устойчивость кода
Благодарю paratagas за ценное дополнение:
Для большей устойчивости программы (особенно при операциях записи) можно оборачивать инструкции обращения к БД в блоки «try-except-else» и использовать встроенный в sqlite3 «родной» объект ошибок, например, так:
UPD: Использование with в psycopg2
Благодарю KurtRotzke за ценное дополнение:
Последние версии psycopg2 позволяют делать так:
Некоторые объекты в Python имеют __enter__ и __exit__ методы, что позволяет «чисто» взаимодействовать с ними, как в примере выше.
UPD: Ипользование row_factory
Благодарю remzalp за ценное дополнение:
Использование row_factory позволяет брать метаданные из запроса и обращаться в итоге к результату, например по имени столбца.
По сути — callback для обработки данных при возврате строки. Да еще и полезнейший cursor.description, где есть всё необходимое.
Пример из документации: