API-спецификация баз данных языка Python, версия 2.0


Оглавление (нажмите, чтобы открыть):

Доступ к базе данных SQLite из Python

Модуль sqlite3, входит в состав стандартной библиотеки Python, начиная с версии 2.5, и в дополнительной установке не нуждается. Если необходимо получить доступ к SQLite в предыдущих версиях Python, то следует воспользоваться модулем pysqlite. Этот модуль не входит в состав стандартной библиотеки, поэтому его придется устанавливать отдельно.

Для работы с базами данных в языке Python существует единый интерфейс доступа. Все разработчики модулей, осуществляющих связь базы данных с Python, должны придерживаться спецификации DB-API (DataBase Application Program Interface). Это спецификация более интересна для разработчиков модулей, чем для прикладных программистов, поэтому мы не будем ее подробно рассматривать.

Модуль sqlite3 поддерживает спецификацию DB-API 2.0, а так же предоставляет некоторые нестандартные возможности. Поэтому, изучив методы и атрибуты этого модуля, вы получите достаточно подробное представление о спецификации DB API 2.0 и сможете в дальнейшем работать с другой базой данных. Получить номер спецификации, поддерживаемой модулем, можно с помощью атрибута apilevel:

Получить номер версии используемого модуля sqlite3 можно с помощью атрибутов sqlite_version и sqlite_version_info. Атрибут sqlite_version возвращает номер версии в виде строки, а атрибут sqlite_version_info в виде кортежа из трех чисел. Пример:

Согласно спецификации DB-API 2.0 последовательность работы с базой данных выглядит следующим образом:

1. Производится подключение к базе данных с помощью функции connect(). Функция возвращает объект соединения, с помощью которого осуществляется дальнейшая работа с базой данных.

2. Создается объект-курсора.

3. Выполняется SQL-запросы и обрабатывается результаты. Перед выполнением первого запроса, который изменяет записи (INSERT, REPLACE, UPDATE и DELETE), автоматически запускается транзакция.

4. Завершается транзакция или отменяются все изменения в рамках транзакции.

5. Закрывается объекты курсор.

6. Закрывается соединение с базой данных.

Про любой модуль, язык программирования можно узнать подробней на всемирной энциклопедии Wikipedia. Данный ресурс уже подтвердил свою необходимость в повседневной жизни многих студентов, ученых и простых людей.

Python Database API Specification 2.0В¶

KInterbasDB is the Python Database API 2.0 compliant driver for Firebird. The Reference / Usage Guide is therefore divided into three parts:

  • Python Database API 2.0 specification
  • KInterbasDB Compliance to Python DB 2.0 API specification.
  • KInterbasDB features beyond Python DB 2.0 API specification.

If you’re familiar to Python DB 2.0 API specification, you may skip directly to the next topic.

This is a local copy of the specification. The online source copy is available at http://www.python.org/topics/database/DatabaseAPI-2.0.html

Introduction¶

This API has been defined to encourage similarity between the Python modules that are used to access databases. By doing this, we hope to achieve a consistency leading to more easily understood modules, code that is generally more portable across databases, and a broader reach of database connectivity from Python.

The interface specification consists of several sections:

  • Module Interface
  • Connection Objects
  • Cursor Objects
  • Type Objects and Constructors
  • Implementation Hints
  • Major Changes from 1.0 to 2.0

Comments and questions about this specification may be directed to the SIG for Database Interfacing with Python.

For more information on database interfacing with Python and available packages see the Database Topics Guide on www.python.org.

This document describes the Python Database API Specification 2.0. The previous version 1.0 version is still available as reference. Package writers are encouraged to use this version of the specification as basis for new interfaces.

Module Interface¶

Access to the database is made available through connection objects. The module must provide the following constructor for these:

connect(parameters. )В¶ Constructor for creating a connection to the database. Returns a Connection Object . It takes a number of parameters which are database dependent. [1]

These module globals must be defined:

apilevelВ¶ String constant stating the supported DB API level. Currently only the strings ‘1.0’ and ‘2.0’ are allowed. If not given, a Database API 1.0 level interface should be assumed. threadsafetyВ¶

Integer constant stating the level of thread safety the interface supports. Possible values are:

  • 0 = Threads may not share the module.
  • 1 = Threads may share the module, but not connections.
  • 2 = Threads may share the module and connections.
  • 3 = Threads may share the module, connections and cursors. Sharing in the above context means that two threads may use a resource without wrapping it using a mutex semaphore to implement resource locking.

Note that you cannot always make external resources thread safe by managing access using a mutex: the resource may rely on global variables or other external sources that are beyond your control.

String constant stating the type of parameter marker formatting expected by the interface. Possible values are [2]:

  • ‘qmark’ = Question mark style, e.g. ‘. WHERE name=?’
  • ‘numeric’ = Numeric, positional style, e.g. ‘. WHERE name=:1’
  • ‘named’ = Named style, e.g. ‘. WHERE name=:name’
  • ‘format’ = ANSI C printf format codes, e.g. ‘. WHERE name=%s’
  • ‘pyformat’ = Python extended format codes, e.g. ‘. WHERE name=%(name)s’

The module should make all error information available through these exceptions or subclasses thereof:

exception WarningВ¶ Exception raised for important warnings like data truncations while inserting, etc. It must be a subclass of the Python StandardError (defined in the module exceptions). exception ErrorВ¶ Exception that is the base class of all other error exceptions. You can use this to catch all errors with one single ‘except’ statement. Warnings are not considered errors and thus should not use this class as base. It must be a subclass of the Python StandardError (defined in the module exceptions). exception InterfaceErrorВ¶ Exception raised for errors that are related to the database interface rather than the database itself. It must be a subclass of Error. exception DatabaseErrorВ¶ Exception raised for errors that are related to the database. It must be a subclass of Error. exception DataErrorВ¶ Exception raised for errors that are due to problems with the processed data like division by zero, numeric value out of range, etc. It must be a subclass of DatabaseError. exception OperationalErrorВ¶ Exception raised for errors that are related to the database’s operation and not necessarily under the control of the programmer, e.g. an unexpected disconnect occurs, the data source name is not found, a transaction could not be processed, a memory allocation error occurred during processing, etc. It must be a subclass of DatabaseError. exception IntegrityErrorВ¶ Exception raised when the relational integrity of the database is affected, e.g. a foreign key check fails. It must be a subclass of DatabaseError. exception InternalErrorВ¶ Exception raised when the database encounters an internal error, e.g. the cursor is not valid anymore, the transaction is out of sync, etc. It must be a subclass of DatabaseError. exception ProgrammingErrorВ¶ Exception raised for programming errors, e.g. table not found or already exists, syntax error in the SQL statement, wrong number of parameters specified, etc. It must be a subclass of DatabaseError. exception NotSupportedErrorВ¶ Exception raised in case a method or database API was used which is not supported by the database, e.g. requesting a .rollback() on a connection that does not support transaction or has transactions turned off. It must be a subclass of DatabaseError.

This is the exception inheritance layout:

Connection Objects¶

Connections Objects should respond to the following methods:

>Connection¶ close()¶ Close the connection now (rather than whenever __del__ is called). The connection will be unusable from this point forward; an Error (or subclass) exception will be raised if any operation is attempted with the connection. The same applies to all cursor objects trying to use the connection. commit()¶ Commit any pending transaction to the database. Note that if the database supports an auto-commit feature, this must be initially off. An interface method may be provided to turn it back on. Database modules that do not support transactions should implement this method with void functionality. rollback()¶ This method is optional since not all databases provide transaction support. [3] In case a database does provide transactions this method causes the the database to roll back to the start of any pending transaction. Closing a connection without committing the changes first will cause an implicit rollback to be performed. cursor()¶ Return a new Cursor Object using the connection. If the database does not provide a direct cursor concept, the module will have to emulate cursors using other means to the extent needed by this specification. [4]

Cursor Objects¶

These objects represent a database cursor, which is used to manage the context of a fetch operation. Cursor Objects should respond to the following methods and attributes:

>CursorВ¶ descriptionВ¶ This read-only attribute is a sequence of 7-item sequences. Each of these sequences contains information describing one result column: (name, type_code, display_size, internal_size, precision, scale, null_ok) . This attribute will be None for operations that do not return rows or if the cursor has not had an operation invoked via the executeXXX() method yet. The type_code can be interpreted by comparing it to the Type Objects specified in the section below. rowcountВ¶ This read-only attribute specifies the number of rows that the last executeXXX() produced (for DQL statements like select) or affected (for DML statements like update or insert ). The attribute is -1 in case no executeXXX() has been performed on the cursor or the rowcount of the last operation is not determinable by the interface. [7] callproc(procname [ , parameters ] )В¶ This method is optional since not all databases provide stored procedures. [3] Call a stored database procedure with the given name. The sequence of parameters must contain one entry for each argument that the procedure expects. The result of the call is returned as modified copy of the input sequence. Input parameters are left untouched, output and input/output parameters replaced with possibly new values. The procedure may also provide a result set as output. This must then be made available through the standard fetchXXX() methods. close()В¶ Close the cursor now (rather than whenever __del__ is called). The cursor will be unusable from this point forward; an Error (or subclass) exception will be raised if any operation is attempted with the cursor. execute(operation [ , parameters ] )В¶ Prepare and execute a database operation (query or command). Parameters may be provided as sequence or mapping and will be bound to variables in the operation. Variables are specified in a database-specific notation (see the module’s paramstyle attribute for details). [5] A reference to the operation will be retained by the cursor. If the same operation object is passed in again, then the cursor can optimize its behavior. This is most effective for algorithms where the same operation is used, but different parameters are bound to it (many times). For maximum efficiency when reusing an operation, it is best to use the setinputsizes() method to specify the parameter types and sizes ahead of time. It is legal for a parameter to not match the predefined information; the implementation should compensate, possibly with a loss of efficiency. The parameters may also be specified as list of tuples to e.g. insert multiple rows in a single operation, but this kind of usage is depreciated: executemany() should be used instead. Return values are not defined. executemany(operation, seq_of_parameters)В¶ Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters . Modules are free to implement this method using multiple calls to the execute() method or by using array operations to have the database process the sequence as a whole in one call. The same comments as for execute() also apply accordingly to this method. Return values are not defined. fetchone()В¶ Fetch the next row of a query result set, returning a single sequence, or None when no more data is available. [6] An Error (or subclass) exception is raised if the previous call to executeXXX() did not produce any result set or no call was issued yet. fetchmany( [ size=cursor.arraysize ] )В¶ Fetch the next set of rows of a query result, returning a sequence of sequences (e.g. a list of tuples). An empty sequence is returned when no more rows are available. The number of rows to fetch per call is specified by the parameter. If it is not given, the cursor’s arraysize determines the number of rows to be fetched. The method should try to fetch as many rows as indicated by the size parameter. If this is not possible due to the specified number of rows not being available, fewer rows may be returned. An Error (or subclass) exception is raised if the previous call to executeXXX() did not produce any result set or no call was issued yet. Note there are performance considerations involved with the size parameter. For optimal performance, it is usually best to use the arraysize attribute. If the size parameter is used, then it is best for it to retain the same value from one fetchmany() call to the next. fetchall()В¶ Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor’s arraysize attribute can affect the performance of this operation. An Error (or subclass) exception is raised if the previous call to executeXXX() did not produce any result set or no call was issued yet. nextset()В¶ This method is optional since not all databases support multiple result sets. [3] This method will make the cursor skip to the next available set, discarding any remaining rows from the current set. If there are no more sets, the method returns None . Otherwise, it returns a true value and subsequent calls to the fetch methods will return rows from the next result set. An Error (or subclass) exception is raised if the previous call to executeXXX() did not produce any result set or no call was issued yet. setinputsizes(sizes)В¶ This can be used before a call to executeXXX() to predefine memory areas for the operation’s parameters. sizes is specified as a sequence – one item for each input parameter. The item should be a Type Object that corresponds to the input that will be used, or it should be an integer specifying the maximum length of a string parameter. If the item is None , then no predefined memory area will be reserved for that column (this is useful to avoid predefined areas for large inputs). This method would be used before the executeXXX() method is invoked. Implementations are free to have this method do nothing and users are free to not use it. setoutputsize(size [ , column ] )В¶ Set a column buffer size for fetches of large columns (e.g. LONGs, BLOBs, etc.). The column is specified as an index into the result sequence. Not specifying the column will set the default size for all large columns in the cursor. This method would be used before the executeXXX() method is invoked. Implementations are free to have this method do nothing and users are free to not use it.

Мастер Йода рекомендует:  Задача про акции Apple

Type Objects and Constructors¶

Many databases need to have the input in a particular format for binding to an operation’s input parameters. For example, if an input is destined for a DATE column, then it must be bound to the database in a particular string format. Similar problems exist for “Row ID” columns or large binary items (e.g. blobs or RAW columns). This presents problems for Python since the parameters to the executeXXX() method are untyped. When the database module sees a Python string object, it doesn’t know if it should be bound as a simple CHAR column, as a raw BINARY item, or as a DATE. To overcome this problem, a module must provide the constructors defined below to create objects that can hold special values. When passed to the cursor methods, the module can then detect the proper type of the input parameter and bind it accordingly. A Cursor Object’s description attribute returns information about each of the result columns of a query. The type_code must compare equal to one of Type Objects defined below. Type Objects may be equal to more than one type code (e.g. DATETIME could be equal to the type codes for date, time and timestamp columns; see the Implementation Hints below for details). The module exports the following constructors and singletons:

Date(year, month, day)В¶ This function constructs an object holding a date value. Time(hour, minute, second)В¶ This function constructs an object holding a time value. Timestamp(year, month, day, hour, minute, second)В¶ This function constructs an object holding a time stamp value. DateFromTicks(ticks)В¶ This function constructs an object holding a date value from the given ticks value (number of seconds since the epoch; see the documentation of the standard Python time module for details). TimeFromTicks(ticks)В¶ This function constructs an object holding a time value from the given ticks value (number of seconds since the epoch; see the documentation of the standard Python time module for details). TimestampFromTicks(ticks)В¶ This function constructs an object holding a time stamp value from the given ticks value (number of seconds since the epoch; see the documentation of the standard Python time module for details). Binary(string)В¶ This function constructs an object capable of holding a binary (long) string value. STRINGВ¶ This type object is used to describe columns in a database that are string-based (e.g. CHAR). BINARYВ¶ This type object is used to describe (long) binary columns in a database (e.g. LONG, RAW, BLOBs). NUMBERВ¶ This type object is used to describe numeric columns in a database. DATETIMEВ¶ This type object is used to describe date/time columns in a database. ROWIDВ¶ This type object is used to describe the “Row ID” column in a database.

SQL NULL values are represented by the Python None singleton on input and output. Note: Usage of Unix ticks for database interfacing can cause troubles because of the limited date range they cover.

Implementation Hints¶

  • The preferred object types for the date/time objects are those defined in the mxDateTime package. It prov >

  • This Python >
  • Here is a snippet of Python code that implements the exception hierarchy defined above:

Major Changes from Version 1.0 to Version 2.0В¶

The Python Database API 2.0 introduces a few major changes compared to the 1.0 version. Because some of these changes will cause existing DB API 1.0 based scripts to break, the major version number was adjusted to reflect this change. These are the most important changes from 1.0 to 2.0:

  • The need for a separate dbi module was dropped and the functionality merged into the module interface itself.
  • New constructors and Type Objects were added for date/time values, the RAW Type Object was renamed to BINARY. The resulting set should cover all basic data types commonly found in modern SQL databases.
  • New constants (apilevel, threadlevel, paramstyle) and methods (executemany, nextset) were added to provide better database bindings.
  • The semantics of .callproc() needed to call stored procedures are now clearly defined.
  • The definition of the .execute() return value changed. Previously, the return value was based on the SQL statement type (which was hard to implement right) – it is undefined now; use the more flexible .rowcount attribute instead. Modules are free to return the old style return values, but these are no longer mandated by the specification and should be considered database interface dependent.
  • Class based exceptions were incorporated into the specification. Module implementors are free to extend the exception layout defined in this specification by subclassing the defined exception classes.

Open Issues¶

Although the version 2.0 specification clarifies a lot of questions that were left open in the 1.0 version, there are still some remaining issues:

  • Define a useful return value for .nextset() for the case where a new result set is available.
  • Create a fixed point numeric type for use as loss-less monetary and decimal interchange format.

Python – доступ к базе данных MySQL

Вы можете выбрать необходимую базу данных для своего приложения. Python Database API поддерживает широкий спектр серверов баз данных, таких как:

  • GadFly
  • mSQL
  • MySQL
  • PostgreSQL
  • Microsoft SQL Server 70000
  • Informix
  • Interbase
  • Oracle
  • Sybase

Ниже приведен список доступных интерфейсов базы данных в Python : интерфейсы базы данных Python и интерфейсы API. Вы должны загрузить отдельный модуль API DB для каждой базы данных, к которой вы должны получить доступ. Например, если вам нужно получить доступ к базе данных Oracle, а также к базе данных MySQL, вы должны загрузить модули базы данных Oracle и MySQL.

API DB предоставляет минимальный стандарт для работы с базами данных с использованием структур и синтаксиса Python, где это возможно. API включает в себя следующее:

  • Импорт модуля API.
  • Получение соединения с базой данных.
  • Выдача операторов SQL и хранимых процедур.
  • Закрытие соединения

Мы бы узнали все понятия, используя MySQL, поэтому давайте поговорим о модуле MySQLdb.

Что такое MySQLdb?

MySQLdb – это интерфейс для подключения к серверу баз данных MySQL из Python. Он реализует Python Database API версии 2.0 и построен поверх API MySQL C.

Как установить MySQLdb?

Прежде чем продолжить, убедитесь, что на вашем компьютере установлена MySQLdb. Просто введите следующее в свой скрипт Python и выполните его:

Если он производит следующий результат, то это означает, что модуль MySQLdb не установлен:

Чтобы установить модуль MySQLdb, используйте следующую команду:

Для Ubuntu, используйте следующую команду:

Для Fedora, используйте следующую команду:

Для командной строки Python используйте следующую команду:

Подключение к базе данных

Прежде чем подключиться к базе данных MySQL, убедитесь в следующем:

  • Вы создали базу данных TESTDB.
  • Вы создали таблицу EMPLOYEE в TESTDB.
  • В этой таблице есть поля FIRST_NAME, LAST_NAME, AGE, SEX and INCOME.
  • Идентификатор пользователя «testuser» и пароль «test123» установлены для доступа к TESTDB.
  • Модуль Python MySQLdb установлен правильно на вашем компьютере.
  • Вы изучили руководство MySQL, чтобы понять основы MySQL.

Пример

Ниже приведен пример подключения к базе данных MySQL “TESTDB”

Результат данного скрипта на нашей машине Linux будет следующий:

Если соединение установлено с источником данных, объект подключения возвращается и сохраняется в db для дальнейшего использования, в противном случае для db установлено значение None. Затем объект db используется для создания объекта- курсора, который, в свою очередь, используется для выполнения SQL-запросов. Наконец, прежде чем выйти, он гарантирует, что соединение с базой данных будет закрыто и ресурсы будут освобождены.

Создание таблицы базы данных

После установления соединения с базой данных мы готовы создавать таблицы или записи в таблицах базы данных, используя метод execute созданного курсора.

Пример

Создадим таблицу базы данных EMPLOYEE:

Операция INSERT

Это необходимо, если вы хотите создать свои записи в таблице базы данных.

Пример

В следующем примере выполняется оператор SQL INSERT для создания записи в таблице EMPLOYEE:

Вышеприведенный пример можно записать следующим образом для динамического создания SQL-запросов:

Пример

Следующий сегмент кода – это еще одна форма выполнения, где вы можете передавать параметры напрямую:

Операция READ

Операция READ в любой базе данных означает получение некоторой полезной информации из базы данных.

Как только наше соединение с базой данных будет установлено, вы готовы сделать запрос в эту базу данных. Вы можете использовать метод fetchone() для извлечения одного метода записи или fetchall() для извлечения нескольких значений из таблицы базы данных.

  • fetchone()выбор следующей строки набора результатов запроса. Набор результатов – это возвращаемый объект, когда объект курсора используется для запроса таблицы.
  • fetchall() – извлекает все строки в результирующем наборе. Если некоторые строки уже извлечены из набора результатов, то он извлекает оставшиеся строки из набора результатов.
  • rowcount – это атрибут только для чтения и возвращает количество строк, на которые повлиял метод execute().

Пример


Следующая процедура запрашивает все записи из таблицы EMPLOYEE с зарплатой более 65000:

Это приведет к следующему результату:

Операция обновления

Операция UPDATE в любой базе данных означает обновление одной или нескольких записей, которые уже доступны в базе данных.

Следующая процедура обновляет все записи, имеющие SEX как «M». Здесь мы увеличиваем возраст всех мужчин на один год.

Пример

Операция DELETE

Операция DELETE требуется, если вы хотите удалить некоторые записи из своей базы данных. Ниже приведена процедура удаления всех записей из EMPLOYEE, где AGE больше 25:

Пример

Выполнение транзакций

Транзакция – это механизм, обеспечивающий согласованность данных. Транзакции имеют следующие четыре свойства:

  • Атомарность (Атомарная операция) — операция, которая либо выполняется целиком, либо не выполняется вовсе; операция, которая не может быть частично выполнена и частично не выполнена.
  • Консистенция – транзакция должна начинаться в согласованном состоянии и оставлять систему в согласованном состоянии.
  • Изоляция. Промежуточные результаты транзакции не видны за пределами текущей транзакции.
  • Долговечность. После совершения транзакции эффекты сохраняются, даже после сбоя системы.

API Python DB 2.0 предоставляет два метода для фиксации транзакции или откат транзакции.

Пример

Вы уже знаете, как реализовать транзакции. Вот еще один пример:

Операция COMMIT

Commit – это операция, которая дает зеленый сигнал базе данных для завершения изменений, и после этой операции никакие изменения не могут быть возвращены обратно.

Вот простой пример вызова метода commit.

Операция ROLLBACK

Если вы не удовлетворены одним или несколькими изменениями и хотите полностью вернуть эти изменения, используйте метод rollback().

Вот простой пример для вызова метода rollback().

Отключение базы данных

Чтобы отключить соединение с базой данных, используйте метод close().

Если соединение с базой данных закрывается пользователем с помощью метода close(), любые незавершенные транзакции откатываются БД. Однако вместо того, чтобы зависеть от какой-либо из деталей реализации более низкого уровня БД, приложению будет лучше вызывать commit или rollback явно.

Обработка ошибок

Существует множество источников ошибок. Несколько примеров – это синтаксическая ошибка в исполняемом SQL-заявлении, сбой подключения или вызов метода выборки для уже отмененного или завершенного дескриптора инструкции.

API БД определяет ряд ошибок, которые должны существовать в каждом модуле базы данных. В приведенной ниже таблице перечислены эти исключения.

Исключение и описание
1 Warning

Используется для нефатальных проблем. Должен быть подкласс StandardError.

2 Error

Базовый класс для ошибок. Должен быть подкласс StandardError.

3 InterfaceError

Используется для ошибок в модуле базы данных, а не для самой базы данных. Должен быть подкласс Error.

4 DatabaseError

Используется для ошибок в базе данных. Должен быть подкласс Error.

5 DataError

Подкласс DatabaseError, который ссылается на ошибки в данных.

6 OperationalError

Подкласс DatabaseError, который относится к ошибкам, например, к потере соединения с базой данных. Эти ошибки, как правило, не контролируются скриптом Python.

7 IntegrityError

Подкласс DatabaseError для ситуаций, которые могут повредить реляционную целостность, такие как ограничения уникальности или внешние ключи.

8 Внутренняя ошибка

Подкласс DatabaseError, который ссылается на внутренние ошибки модуля базы данных, такие как курсор, которые больше не активны.

9 ProgrammingError

Подкласс DatabaseError, который ссылается на такие ошибки, как неправильное имя таблицы и другие вещи, которые можно смело винить вас.

10 NotSupportedError

Подкласс DatabaseError, который ссылается на попытку вызвать неподдерживаемые функциональные возможности.

Ваши скрипты Python должны обрабатывать эти ошибки, но прежде чем использовать какое-либо из вышеперечисленных исключений, убедитесь, что ваш MySQLdb поддерживает это исключение. Вы можете получить дополнительную информацию о них, прочитав спецификацию DB API 2.0.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Python. Лекция. Работа с базой данных.

В этой лекции рассматривается спецификация DB-API 2.0 и модуль для работы с конкретной базой данных, дается начальное представление о языке запросов SQL

В рамках данной лекции были рассмотрены возможности связи Python с системами управления реляционными базами данных. Для Python разработан стандарт, называемый DB-API (версия 2.0), которого должны придерживаться все разработчики модулей сопряжения с реляционными базами данных. Благодаря этому API код прикладной программы становится менее зависимым от марки используемой базы данных, его могут понять разработчики, использующие другие базы данных. Фактически DB-API 2.0 описывает имена функций и классов, которые должен содержать модуль сопряжения с базой данных, и их семантику. Модуль сопряжения должен содержать класс объектов-соединений с базой данных и класс для курсоров — специальных объектов, через которые происходит коммуникация с СУБД на прикладном уровне. Здесь была использована СУБД SQLite и соответствующий модуль расширения Python для сопряжения с этой СУБД — sqlite, так как он поддерживает DB-API 2.0 и достаточно прост в установке. С его помощью были продемонстрированы основные приемы работы с базой данных: создание и наполнение таблиц, выполнение выборок и анализ полученных данных. В конце лекции дан список других пакетов и модулей, которые позволяют Python- программе работать со многими современными СУБД.

Python работа с MySQL

На просторах интернета на данный момент не так много адекватных статей по поводу работы с СУБД MySQL через Python. Эта статья представляет собой простое руководство для быстрого старта.

Я недавно отошёл от использования второй версии языка, и все примеры пишутся на Python 3.x.

И так без лишних слов. Подразумевается что у вас уже установлен MySQL и Python. Для работы с MySQL из Python требуется модуль MySQLdb. Python реализует стандарт для работы с реляционными базами данных Python Database API Specification V2.0 или по другому PEP 249. Модули для доступа к реляционным базам данных должны следовать этому стандарту, но могут вводить свои возможности.

Скачать модуль MySQLdb для необходимой версии Python можно тут:
http://www.lfd.uci.edu/

Теперь создадим тестовую базу данных и таблицу. Для управления базами я использую phpMyAdmin.

Проверим корректность установки модуля MySQLdb. В стандартной IDLE создаем новое окно (File->New Window) или (Ctrl+N) и прописываем следующее:

Жмём F5 или RUN->Rum Module и должны увидеть список городов. Если это произошло, значит всё сделано правильно.

Функций, свойства и методы модуля MySQLdb

Модуль MySQLdb реализует полный функционал стандарта Python Database API Specification V2.0 и некоторый свой функционал. Так же в модуле присутствуют методы, которые отмечены как нестандартные и могут работать не верно. В этом разделе будет кратко описаны основные возможности.

Соединение с базой данных

Для установки соединения с базой данных существует функция MySQLdb.connect.


Так же можно указать port, unix_socket, connect_timeout, compress, charset, sql_mode и некоторые другие (см. документацию)

В случае успеха, функция возвращает объект класса Connection. Экземпляр con класса Connection обладает следующими методами.

  • con.close() – закрывает соединение с сервером базы данных.
  • con.commit() – подтверждает все незавершенные транзакции
  • con.rollback() – откатывает все изменение в базе данных до момента когда были запущенные незавершённые транзакции.
  • con.cursor() – создаёт новый курсор. Это экземпляр класса Cursor. Курсор – это объект, который используется для SQL запросов и получения результата.
  • con.autocommit() – используется для автоматического завершения транзакции.
  • con.affected_rows() — возвратите число строк, на которые повлиял последний запрос. Лучше использовать cur.rowcount(). (не стандартный)
  • con.errno() – возвращает номер ошибки если она произошла.
  • con.error() – возвращает описание ошибки если она произошла.
  • con.select_db() – используется для выбора базы данных. (не стандартный)
  • con.insert_id() – Возвращает ID, сгенерированный для столбца AUTO_INCREMENT предыдущим запросом
  • con.escape() – используется для экранирования символов (см. документацию)
  • con.escape_string() – используется для экранирования символов (см. документацию)
  • con.string_literal() – используется для экранирования символов (см. документацию)

Так же модуль имеет ещё ряд нестандартных методов, при желании с ними можно ознакомиться в документации.

Курсор

Что бы выполнить какие-то операции в базе данных, сначала требуется создать объект соединения con, а затем вызвать метод con.cursor() создав курсор. Методы и свойства экземпляра cur класса Cursor используются для выполнения запросов к базе данных.

  • cur.close() – закрывает курсор предотвращая выполнения каких либо запросов с его помощью.
  • cur.callproc(procname [, param]) – вызывает хранимую процедуру.
  • cur.execute(query [, param]) – выполняет запрос к базе данных (query).
  • cur.executemany(query [, paramsequence]) – многократное выполнение запросов к базе данных (query).
  • cur.fetchone() – возвращает следующую запись из набора данных полученого вызовом cur.execute*()
  • cur.fetchmany([size]) – возвращает последовательность записей из набора данных.
  • cur.fetchall() – возвращает последовательность всех записей оставшихся в полученном наборе данных.
  • cur.nextset() – пропускает все оставшиеся записи в текущем наборе данных и переходит к следующему набору.
  • cur.setinputsize(sizes) – сообщает курсору о параметрах, которые будут переданы в последующих вызовах методов cur.execute*()
  • cur.setoutputsize(sizes [, column]) – устанавливает размер буфера для определённого столбца в возвращаемом наборе данных.
  • cur.description — возвращает последовательность кортежей с информацией о каждом столбце в текущем наборе данных. Кортеж имеет вид (name, type_code, display_size, internal_size, precision, scale, null_ok)
  • cur.arraysize – целое число которое используется методом cur.fetchmany как значение по умолчанию.
  • cur.rowcount — возвратите число строк, на которые повлиял последний запрос.

Способы выборки из таблиц

Объект cursor модуля MySQLdb поддерживает итерации. Это значит, что можно обойти все записи в наборе данных полученных из cur.execute без использования метода cur.fetchall, а просто используя инструкцию for row in cur:

Так же за место цикла for можно использовать цикл while

Обращение к данным по ключам может показаться неудобным, особенно если вы работает с большим набором данных из большого числа столбцов. Намного привычнее обращаться к данным по именам полей. Для этого напишем небольшую функцию-генератор. Вообще лучше сесть и написать хорошую обёртку во круг всего этого модуля. Например, можно динамически создавать курсор или даже делать коннект к базе.

Функцию-генератор по «именовыванию» последовательности записей.

Использовать её можно следующим образом:

Формирование запросов

Важным этапом в работе с базой данных является формирование запросов к этой базе данных. Отчасти проблема заключается в необходимости вставлять в строку запроса данные пользовательского ввода, что абсолютно не безопасно. Далее об этом.

Экранирование символов. В MySQLdb есть 4 метода экранирования:

  1. con.escape
  2. con.escape_string
  3. con.string_literal
  4. И автоматический механизм подстановки значений:cur.execute(«SELECT *FROM `city` WHERE >Тут символ подстановки (?) замещается значением из кортежа (city,) автоматически экранируя спец. символы.

Но не существует единого правила оформления подстановки значений в запрос. Поэтому есть переменная paramstyle которая может определить формат подстановки.

У меня MySQLdb.paramstyle равен ‘format’.

  1. qmark – параметры обозначаются знаков вопроса (?)
  2. numeric — параметры обозначаются числами
  3. named — параметры обозначаются именами
  4. format — параметры обозначаются в стиле printf.
  5. pyformat — параметры обозначаются в стиле расширенного набора кодов формата Python — %(name)s

Но есть небольшая проблема.

В Python 3.x такой подход работать не будет. Если заглянуть под капот модуля MySQLdb и найти функцию execute (\Lib\site-packages\MySQLdb\cursors.py), то можно видеть что в Python 3.x подстановка параметров осуществляется используя функцию format:

А в Python 2.x используется простое формирование строки:

По всей видимости, разработчики забыли изменить документацию к функции. И поэтому формирование в стиле Си функции printf работает не будет.

Следовательно, нужно использовать следующий подход:

Говоря об экранирование, используя функции escape_string и string_literal, они не работают с кодировками, что является серьёзной проблемой. Раньше была функция escape которая принимала один параметр, но теперь ей требуется 2 параметра, причём второй это словарь с ссылками на функции каждого из типов, и честно говоря для меня он остался загадкой. Поэтому лучше использовать вариант с автоматическим экранированием. Автоматическое экранирование спец. символов реализовано используя функцию escape.

Если вы разрабатываете Web приложение, то стоит позаботиться о преобразование символов & « в соответствующие сущности языка разметки, такие как & «. Для этого можно использовать функцию escape() модуля cgi:

Или написать что-то своё, с более расширенным функционалом.

Обратите внимание на VALUES (), метку не нужно загонять в кавычки. Автоматическая подстановка сделает это за Вас, иначе будет выведено сообщение об ошибке.

Вот наверно и всё, что я хотел рассказать. Думаю этого достаточно для нормального старта с базой данных MySQL. Удачных экспериментов!

Работа с базой данных

Основные понятия реляционной СУБД

Реляционная база данных — это набор таблиц с данными.

Таблица — это прямоугольная матрица , состоящая из строк и столбцов. Таблица задает отношение ( relation ).

Строка — запись , состоящая из полей — столбцов. В каждом поле может содержаться некоторое значение , либо специальное значение NULL (пусто). В таблице может быть произвольное количество строк. Для реляционной модели порядок расположения строк не определен и не важен.

Каждый столбец в таблице имеет собственное имя и тип.

Что такое DB-API 2

Вынесенная в заголовок аббревиатура объединяет два понятия: DB ( Database , база данных ) и API ( Application Program Interface , интерфейс прикладной программы).

Таким образом, DB- API определяет интерфейс прикладной программы с базой данных. Этот интерфейс , описываемый ниже, должны реализовывать все модули расширения, которые служат для связи Python -программ с базами данных. Единый API (в настоящий момент его вторая версия) позволяет абстрагироваться от марки используемой базы данных , при необходимости довольно легко менять одну СУБД на другую, изучив всего один набор функций и методов.

DB- API 2.0 описан в PEP 249 ( сайт http://www.python.org/dev/peps/pep-0249/), и данное ниже описание основано именно на нем.

Описание DB API 2.0

DB API 2.0 регламентирует интерфейсы модуля расширения для работы с базой данных, методы объекта-соединения с базой, объекта-курсора текущей обрабатываемой записи, объектов различных для типов данных и их конструкторов, а также содержит рекомендации для разработчиков по реализации модулей. На сегодня Python поддерживает через модули расширения многие известные базы данных (уточнить можно на web-странице по адресу http://www.python.org/topics/database/). Ниже рассматриваются почти все положения DB- API за исключением рекомендаций для разработчиков новых модулей.

Интерфейс модуля

Здесь необходимо сказать о том, что должен предоставлять модуль для удовлетворения требований DB-API 2.0.

Доступ к базе данных осуществляется с помощью объекта-соединения (connection object). DB-API- совместимый модуль должен предоставлять функцию-конструктор connect() для класса объектов-соединений. Конструктор должен иметь следующие именованные параметры:

  • dsn Название источника данных в виде строки
  • user Имя пользователя
  • password Пароль
  • host Адрес хоста, на котором работает СУБД
  • database Имя базы данных.

Методы объекта-соединения будут рассмотрены чуть позже.


Модуль определяет константы, содержащие его основные характеристики:

  • apilevel Версия DB-API («1.0» или «2.0»).
  • threadsafety Целочисленная константа, описывающая возможности модуля при использовании потоков управления:
    • 0 Модуль не поддерживает потоки.
    • 1 Потоки могут совместно использовать модуль, но не соединения.
    • 2 Потоки могут совместно использовать модуль и соединения.
    • 3 Потоки могут совместно использовать модуль, соединения и курсоры. (Под совместным использованием здесь понимается возможность использования упомянутых ресурсов без применения семафоров).

    Модуль должен определять ряд исключений для обозначения типичных исключительных ситуаций: Warning (предупреждение), Error (ошибка), InterfaceError (ошибка интерфейса), DatabaseError (ошибка, относящаяся к базе данных). А также подклассы этого последнего исключения: DataError (ошибка обработки данных), OperationalError (ошибка в работе или сбой соединения с базой данных), IntegrityError (ошибка целостности базы данных), InternalError (внутренняя ошибка базы данных), ProgrammingError (программная ошибка, например, ошибка в синтаксисе SQL-запроса), NotSupportedError (при отсутствии поддержки запрошенного свойства).

    Анализ данных с помощью pandas. Часть 8: работа с данными из базы данных SQL

    До этого момента, мы получали данные только из csv файлов. Это довольно распространённый способ сохранения данных, но далеко не единственный! Pandas может работать с данными из HTML, JSON, SQL, Excel (. ), HDF5, Stata, и некоторых других вещей. В этой части мы поговорим о работе с данными из баз данных SQL.

    Чтение из SQL баз данных

    Загрузить данные из SQL базы можно с помощью функции pd.read_sql . read_sql автоматически преобразует столбцы SQL в столбцы DataFrame.

    read_sql принимает 2 аргумента: запрос SELECT , и connection. Это здорово, так как это означает, что можно читать из любого вида базы данных — неважно, MySQL, SQLite, PostgreSQL, или другая.

    В этом примере мы читаем из базы SQLite, но другие читаются точно также. Файл, с которым мы будем работать.

    §1 Язык программирования Python

    Общая характеристика языка

    Официальная эмблема Python (зарегистрированная марка)

    Python — мощный и простой для изучения язык программирования. В нём предоставлены удобные высокоуровневые структуры данных и простой, но эффективный подход к объектно-ориентированному программированию. Python интерпретируемый язык. Для запуска написанных программ требуется наличие интерпретатора CPython . Интерпретатор python и большая стандартная библиотека находятся в свободном доступе в виде исходных и бинарных файлов для всех основных платформ на официальном сайте Python http://www.python.org и могут распространяться без ограничений. Кроме этого на сайте содержатся дистрибутивы и ссылки на многочисленные модули третьих сторон и подробная документация.
    Язык обладает чётким и последовательным синтаксисом, продуманной модульностью и масштабируемостью, благодаря чему исходный код написанных на Python программ легко читаем. Разработчики языка Python придерживаются определённой философии программирования, называемой «The Zen of Python». Её текст выдаётся интерпретатором по команде import this :

    В переводе это звучит так:

      Красивое лучше, чем уродливое. Явное лучше, чем неявное. Простое лучше, чем сложное. Сложное лучше, чем запутанное. Плоское лучше, чем вложенное. Разреженное лучше, чем плотное. Читаемость имеет значение. Особые случаи не настолько особые, чтобы нарушать правила. При этом практичность важнее безупречности. Ошибки никогда не должны замалчиваться. Если не замалчиваются явно. Встретив двусмысленность, отбрось искушение угадать. Должен существовать один — и, желательно, только один — очевидный способ сделать это. Хотя он поначалу может быть и не очевиден, если вы не голландец. Сейчас лучше, чем никогда. Хотя никогда зачастую лучше, чем прямо сейчас. Если реализацию сложно объяснить — идея плоха. Если реализацию легко объяснить — идея, возможно, хороша. Пространства имён — отличная штука! Будем делать их побольше!

    Python — активно развивающийся язык программирования, новые версии выходят примерно раз в два с половиной года. Вследствие этого и некоторых других причин на Python отсутствуют стандарт ANSI, ISO или другие официальные стандарты, их роль выполняет CPython.

    История создания языка

    Разработка языка Python была начата в конце 1980-х годов сотрудником голландского института CWI Гвидо ван Россумом. Распределённой ОС Amoeba требовался расширяемый скриптовый язык для которой Гвидо ван Россум и создал Python. Новый язык позаимствовал некоторые наработки для языка ABC, который был ориентирован на обучение программированию. В феврале 1991 года Гвидо опубликовал исходный текст в ньюсгруппе alt.sources. Название языка произошло не от вида пресмыкающихся. Автор назвал язык в честь популярного британского комедийного телешоу 1970-х «Летающий цирк Монти Пайтона». Тем не менее эмблему языка изображают змеиные головы. После длительного тестирования, вышла первая версия Python 3.0. На сегодня поддерживаются обе ветви развития (Python 3.x и 2.x).

    Гвидо ван Россум

    Python создавался под влиянием множества языков программирования: Modula-3, С, C++, Smalltalk, Lisp, Fortran, Java, Miranda, Icon. Несмотря на то, что Python обладает достаточно самобытным синтаксисом, одним из принципов дизайна этого языка является принцип наименьшего удивления.

    Стандартная библиотека

    Богатая стандартная библиотека является одной из привлекательных сторон Python. Здесь имеются средства для работы со многими сетевыми протоколами и форматами Интернета. Существуют модули для работы с регулярными выражениями, текстовыми кодировками, мультимедийными форматами, криптографическими протоколами, архивами. Помимо стандартной библиотеки существует множество библиотек, предоставляющих интерфейс ко всем системным вызовам на разных платформах.
    Для Python принята спецификация программного интерфейса к базам данных DB-API 2 и разработаны соответствующие этой спецификации пакеты для доступа к различным СУБД: Oracle, MySQL, PostgreSQL, Sybase, Firebird (Interbase), Informix, Microsoft SQL Server и SQLite.
    Библиотека NumPy для работы с многомерными массивами позволяет достичь производительности научных расчётов, сравнимой со специализированными пакетами. SciPy использует NumPy и предоставляет доступ к обширному спектру математических алгоритмов. Numarray специально разработан для операций с большими объёмами научных данных.
    Python предоставляет простой и удобный программный интерфейс Си API для написания собственных модулей на языках Си и C++. Такой инструмент как SWIG позволяет почти автоматически получать привязки для использования C/C++ библиотек в коде на Python. Инструмент стандартной библиотеки ctypes позволяет программам Python напрямую обращаться к динамическим библиотекам, написанным на Си. Существуют модули, позволяющие встраивать код на С/C++ прямо в исходные файлы Python, создавая расширения «на лету».
    Python и подавляющее большинство библиотек к нему бесплатны и поставляются в исходных кодах. Более того, в отличие от многих открытых систем, лицензия никак не ограничивает использование Python в коммерческих разработках и не налагает никаких обязательств кроме указания авторских прав.

    Сферы применения

    Python — стабильный и распространённый язык. Он используется во многих проектах и в различных качествах: как основной язык программирования или для создания расширений и интеграции приложений. На Python реализовано большое количество проектов, также он активно используется для создания прототипов будущих программ. Python используется во многих крупных компаниях.
    Python с пакетами NumPy, SciPy и MatPlotLib активно используется как универсальная среда для научных расчётов в качестве замены распространенным специализированным коммерческим пакетам Matlab, IDL и др.
    В профессиональных программах трехмерной графики, таких как Houdini и Nuke, Python используется для расширения стандартных возможностей программ.

    Получение данных c веб-сайта без API в 3 строки кода на Python

    Рассказываем о том, как можно сэкономить время и нервы при автоматизации процесса получения данных с веб-сайтов без соответствующего API-интерфейса.

    Предположим, что в поисках данных, необходимых для вашего проекта, вы натыкаетесь на такую веб-страницу:

    Вот они — все необходимые данные для вашего проекта.

    Но что же делать, если нужные вам данные находятся на сайте, который не предоставляет API для их получения? Конечно же, можно потратить несколько часов и написать обработчик, который получит эти данные и преобразует их в нужный для вашего приложения формат.

    Но есть и более простое решение — это библиотека Pandas и ее встроенная функция read_html() , которая предназначена для получения данных с html-страниц.

    Прим. перев. В данной статье используется версия Pandas 0.20.3

    XYZ school, Москва, до 250 000 ₽

    Да, все настолько просто. Pandas находит html-таблицы на странице и возвращает их как новый объект DataFrame .

    Теперь попробуем указать Pandas, что первая (а точнее нулевая) строка таблицы содержит заголовки столбцов, а также попросим ее сформировать datetime -объект из строки, находящейся в столбце с датой и временем.

    На выходе мы получим следующий результат:

    Теперь все эти данные находятся в DataFrame -объекте. Если же нам нужны данные в формате json, добавим еще одну строчку кода:

    В результате вы получите данные в формате json с правильным форматированием даты по стандарту ISO 8601:

    При желании данные можно сохранить в CSV или XLS:

    Выполните код и откройте файл calls.csv . Он откроется в приложении для работы с таблицами:

    И, конечно же, Pandas упрощает анализ:

    И обработку данных:

    Результат метода unique :

    Теперь вы знаете, как с помощью Python и Pandas можно быстро получить данные с практически любого сайта, не прилагая особых усилий. Освободившееся время предлагаем посвятить чтению других интересных материалов по Python на нашем сайте.

    блог JOHN_16

    Здесь я планирую размещать небольшие статьи на интересующие меня темы.

    четверг, 24 марта 2011 г.

    Python: модуль sqlite3. Перевод документации с примерами.

    SQLite это библиотека написанная на языке C, которая предоставляет легковесную, находящуюся на диске базу данных, которой не требуется отдельный серверный процесс и которая позволяет получать доступ используя не стандартные диалекты языка SQL. Некоторые приложения могут использовать SQLite для внутреннего хранения данных. Также возможно сделать прототип приложения используя SQLite и затем перенести код для больших баз данных, таких как PostgreSQL или Oracle.

    sqlite3 была написана Gerhard Häring и предоставляет SQL интерфейс совместимый с DB-API 2.0 спецификациями описанными в PEP 249.

    Для использования модуля, сначала нужно создать Connection объект олицетворяет базу данных. В данном примере данные будут храниться в файле /tmp/example :

    Также можно использовать специальное имя :memory: для создания базы данных в ОЗУ

    Создав ранее объект Connection можно создать объект Cursor и вызвать его метод execute() для выполнения SQL команд:


    Обычно для выполнения SQL операций необходимо использовать значения из переменных Python. Не рекомендуется собирать запрос используя строковые операции Питона потому что это может быть не безопасным, это делает программу уязвимой к инъекционным SQL атакам.

    Вместо этого используйте DB-API подстановку параметров. Вставьте символ ? в качестве заполнителя в месте где вы хотите использовать значение и предоставьте кортеж значений в качестве второго аргумента метода курсора execute() . (Другие модули баз данных могут использовать другие заполнители, такие как %s или :l ). Пример:

    Что бы получить данные, после выполнения оператора SELECT, можно обработать курсор как итератор, вызвать метод fetchone() что бы получить одиночный ряд, или вызвать fetchall() что бы получить список соответствующих строк. Например:

    print ‘1st example’
    c.execute( ‘select * from stocks order by price’ )
    for row in c:
    print row

    print ‘2nd example’
    c.execute( ‘select * from stocks order by price’ )
    while True:
    tmp=c.fetchone()
    if tmp:
    print tmp
    else:
    break

    print ‘3rd example’
    c.execute( ‘select * from stocks order by price’ )
    print c.fetchall()

    Когда к базе данных получают доступ многократные соединения, и один из процессов изменяет базу данных, база данных SQLite блокируется, до тех пор пока та транзакция не зафиксируется (commit). Параметр timeout определяет, сколько времени соединение должно ждать блокировки, чтобы уйти до возбуждения исключения. Значение по умолчанию для параметра тайм-аута 5.0 (пять секунд).

    Описание параметра isolation_level приведено в разделе Connection объекта.

    SQLite нативно поддерживает только следующие типы данных: TEXT, INTEGER, FLOAT, BLOB, NULL. Если имеется необходимость использовать другие типы, то реализация их поддержки является самостоятельной задачей. Использование параметра detect_types и специальных конверторов, зарегистрированных с помощью функции register_convertor() , позволит легко сделать это.

    detect_types по умолчанию равен 0 (т.е., обнаружение типов выключено), возможные значения представляют собой любые комбинации PARSE_DECLTYPES и PARSE_COLNAMES.

    По умолчанию модуль sqlite3 использует класс Connection для соединений. Тем не менее, возможно разделить на подклассы класс Connection и сделать connect() используя свой класс, указав его в параметре factory.

    sqlite3 модуль использует внутренний кэш операторов что бы избежать издержек при парсинге SQL запросов. Что бы явно задать число операторов для кеширования, необходимо задать параметр cashed_statements. По умолчанию он равен значению 100.

    Функция может возвращать любой тип данных поддерживаемый SQLite: unicode, str, int, long, float,buffer,None.

    import sqlite3
    import md5
    def md5sum(t):
    return md5.md5(t).hexdigest()

    con = sqlite3.connect( «:memory:» )
    con.create_function( «md5» , 1, md5sum)
    cur = con.cursor()
    cur.execute( «select md5(?)» , ( «foo» ,))
    print cur.fetchone()[0]

    Агрегированный класс должен предоставлять метод step , который принимает число параметров num_params, и метод finalize , который будет возвращать окончательный результат.

    Метод finalize может возвращать любой тип данных поддерживаемых SQLite.

    class MySum:
    def __init__(self):
    self.count = 0

    def step(self, value):
    self.count += value

    def finalize(self):
    return self.count

    con = sqlite3.connect( «:memory:» )
    con.create_aggregate( «mysum» , 1, MySum)
    cur = con.cursor()
    cur.execute( «create table test(i)» )
    cur.execute( «insert into test(i) values (1)» )
    cur.execute( «insert into test(i) values (10)» )
    cur.execute( «insert into test(i) values (15)» )

    cur.execute( «select mysum(i) from test» )
    print cur.fetchall()

    Помните, что все вызываемые объекты принимают параметры в качестве строки кодированной в UTF-8 кодировке. Пример:

    alphabet=[chr(i) for i in xrange(97,123)]

    def collate_reverse(string1, string2):
    return -cmp(string1, string2)

    con = sqlite3.connect( «:memory:» )
    con.create_collation( «reverse» , collate_reverse)
    cur = con.cursor()
    cur.execute( «create table test(x)» )
    cur.executemany( «insert into test(x) values (?)» , alphabet)

    cur.execute( «select x from test order by x» )
    print ‘print alphabet’
    print cur.fetchall()

    cur.execute( «select x from test order by x collate reverse» )
    print ‘print reverse alphabet’
    print cur.fetchall()

    Что бы удалить действие сравнения необходимо вызвать create_collation со значением параметра callable равным None :

    Первый параметр, передаваемый в функцию обратного вызова, означает, какого рода операция должна быть авторизированна. Второй и третий параметры должны быть аргументы или None в зависимости от первого аргумента. Четвертый аргумент это название базы данных ( “main”,”temp” и т.д.) если это применимо. Пятый аргумент это имя внутреннего триггера or view that is responsible for the access attempt или None если это попытка доступа из самого SQL запроса.

    Эта подпрограмма регистрирует функцию обратного вызова(callback). Обратный вызов вызывается каждые n инструкций виртуальной машины SQLite. Это полезно если вы хотите быть вызванными из SQLite во время продолжительных операций, например для обновления GUI. Присвоение параметру значения None отключит работу данного метода.

    Этот метод позволяет или не позволяет движку SQLite загружать библиотеки расширений, которые могут определять новые функции, агрегаты или реализации новых виртуальных таблиц. Хорошо известно расширение полнотекстового поиска поставляемое с SQLite.
    Пример смотри ниже.

    Загрузка библиотеки расширений SQLite. Перед использованием необходимо включить поддержку расширений с помощью enable_load_extension() . Пример:

    # -*- coding: utf-8 -*-
    import sqlite3

    workers=(( ‘John’ ,3,10000),( ‘Nik’ ,5,15000))

    def dict_factory(cursor, row):
    d = <>
    for idx, col in enumerate(cursor.description):
    d[col[0]] = row[idx]
    return d

    con = sqlite3.connect( «:memory:» )
    con.row_factory = dict_factory
    cur = con.cursor()
    cur.execute( «create table test(name text, experience integer, screw integer)» )
    cur.executemany( ‘insert into test(name,experience,screw) values (. )’ ,workers)
    cur.execute( ‘select * from test’ )

    for item in cur.fetchall():
    print ‘worker %s have %i years of experience and %i $ of screw’ %(item[ ‘name’ ],item[ ‘experience’ ],item[ ‘screw’ ])

    Если возвращаемого кортежа недостаточно, и вы хотите основанный на имени доступ к столбцам, то вы должны рассматривать настройку row_factory как высоко-оптимизированную sqlite3.Row. Тип Row предоставляет доступ к столбцам, как на основе индексов, так и на основе чувствительным к регистру именам почти без издержек памяти. Это, возможно, даже лучшее решение чем собственный словарь или даже решение основанное на db_row.

    По причинам эффективности существует также другой способ возвращать объекты Unicode только для не-ASCII данных и строк байтов. Для его активации установите этот атрибут в значение sqlite3.OptimizedUnicode.

    Также возможно присвоение ему любого вызываемого объекта принимающего на входе одиночную строку и возвращающую результирующий объект.

    Пример ниже демонстрирует варианты применения параметра. Для наглядности работы функции mystr изменяющей выходную кодировку строки использовалась консоль ОС Windows XP:

    # -*- encoding: utf-8 -*-
    import sqlite3,sys

    def mystr(input):
    # здесь можно сделать все что угодно
    return unicode(input, ‘u8’ ).encode( ‘cp866’ )
    # подготавливаем данные
    data=[ ‘Россия’ .decode( ‘u8’ ), ‘England’ ]

    # создаем таблицу, вносим данные
    con = sqlite3.connect( «:memory:» )
    cur = con.cursor()
    cur.execute( «create table country(name text)» )
    for i in data:
    cur.execute( ‘insert into country values (?)’ ,(i,))

    print u’По умолчанию все объекты возвращаются типом Unicode’
    cur.execute( ‘select * from country’ )
    for i in cur.fetchall():
    print i[0],type(i[0])

    print ‘-‘ *10
    print u’Выходные данный типа str ‘
    con.text_factory=str
    cur.execute( ‘select * from country’ )
    for i in cur.fetchall():
    print i[0],type(i[0])

    print ‘-‘*10
    print u’Использование преобразующей функции mystr’
    con.text_factory=mystr
    cur.execute( ‘select * from country’ )
    for i in cur.fetchall():
    print i[0],type(i[0])

    print ‘-‘ *10
    print u’Использование OptimizedUnicode ‘
    con.text_factory=sqlite3.OptimizedUnicode
    cur.execute( ‘select * from country’ )
    for i in cur.fetchall():
    print i[0],type(i[0])

    Возвращает итератор к дампу базы данных в SQL текстовом формате. Полезна для сохранения базы данных в памяти для последующего восстановления. Эта функция обеспечивает те же самые возможности как .dump команда в оболочке sqlite3.
    Пример ниже демонстрирует весь цикл работы:

    Пример показывает как использовать параметры обоими стилями:

    import sqlite3
    con = sqlite3.connect( «:memory:» )
    cur = con.cursor()
    cur.execute( «CREATE TABLE people(name_last TEXT, age INTEGER)» )
    cur.executemany( «INSERT INTO people VALUES(. )» ,[( ‘Smart’ ,32),( ‘Tesla’ ,87),( ‘Yeltsin’ ,72)])

    who = «Yeltsin»
    age = 72
    cur.execute( «select name_last, age from people where name_last=? and age=?» , (who, age))
    print cur.fetchone()

    cur.execute( «select name_last, age from people where name_last=:who and age=:age» ,< "who" : who, "age" : age>)
    print cur.fetchone()

    execute() выполняет одиночное SQL выражение. Если попытаться выполнить более чем одно выражение то будет возбуждено Предупреждение. Используйте executescript() если необходимо выполнить многократные SQL выражения за один вызов.

    Пример с использованием итератора:


    class IterChars:
    def __init__(self):
    self.count = ord( ‘a’ )
    def __iter__(self):
    return self
    def next(self):
    if self.count > ord( ‘z’ ):
    raise StopIteration
    self.count += 1
    return (chr(self.count — 1),) # this is a 1-tuple

    con = sqlite3.connect( «:memory:» )
    cur = con.cursor()
    cur.execute( «create table characters(c)» )
    theIter = IterChars()
    cur.executemany( «insert into characters(c) values (?)» , theIter)
    cur.execute( «select c from characters» )
    print cur.fetchall()

    import sqlite3
    def char_generator():
    import string
    for c in string.letters[:26]:
    yield (c,)

    con = sqlite3.connect( «:memory:» )
    cur = con.cursor()
    cur.execute( «create table characters(c)» )
    cur.executemany( «insert into characters(c) values (?)» , char_generator())
    cur.execute( «select c from characters» )
    print cur.fetchall()

    Количество получаемых за раз рядов указывается параметром size. Если он не задан, то количество получаемых рядов определяется параметров arraysize курсора. Метод постарается получить настолько много рядов сколько указано параметром. Если это не возможно, то будет возвращено меньшее число рядов.

    Примечание. Существуют некоторые соображения производительности касательно параметра size. Для оптимальной производительности обычно лучше использовать атрибут arraysize. Если используется параметр size, то лучше для этого сохранить тоже самое значение от одного вызова fetchmany() до другого.

    Для выражений DELETE SQLite сообщает rowcont как 0 если сделать DELETE FROM table без каких либо условий.

    Для выражения executemany() число модификаций суммируется вплоть до rowcount. Как требуется Спецификацией API DB Python, атрибут rowcount “-1 в случае, если никакой executeXX () не был выполнен на курсоре, или rowcount последней работы не определим интерфейсом”.

    Так же это включает в себя оператор SELECT, потому что не возможно определить число рядов в результате запроса пока все строки не были выбраны.

    Также это установлено для оператора SELECT без любых строк соответствия.

    Если два объекта Row имеют точно такие же столбцы и их элементы равны, то они сравниваются как равные.

    Изменения в версии 2.6: Добавлены итерации и равенство (подобие хэша)

    # -*- coding: utf-8 -*-
    import sqlite3
    # создаем базу и заполянем ее одним значением
    conn = sqlite3.connect( «:memory:» )
    c = conn.cursor()
    c.execute( »’create table stocks(date text, trans text, symbol text, qty real, price real)»’ )
    c.execute( «»»insert into stocks values (‘2006-01-05′,’BUY’,’RHAT’,100,35.14)»»» )
    conn.commit()
    c.close()

    # Демонстрируем возможности Row
    conn.row_factory = sqlite3.Row
    c = conn.cursor()
    c.execute( ‘select * from stocks’ )
    r = c.fetchone()
    print ‘type(r) = ‘ ,type(r)
    print ‘r = ‘ ,r
    print ‘len(r) = ‘ ,len(r)
    print ‘r[2] = ‘ ,r[2]
    print ‘r.keys() = ‘,r.keys()
    print ‘r[qry] = ‘ ,r[ ‘qty’ ]
    for member in r:
    print member

    SQLite нативно поддерживает следующие типы: NULL, INTEGER, REAL, TEXT, BLOB. Нижеперечисленные типы Python могут быть посланы SQLite безо всяких проблем:

    Типы Python Типы SQLite
    None NULL
    int INTEGER
    long INTEGER
    float REAL
    str(UTF-8 encoded) TEXT
    uncode TEXT
    buffer BLOB

    SQLite типы конвертируются в Python по умолчанию следующим образом:

    Типы SQLite Типы Python
    NULL None
    INTEGER int или long, в зависимости от размера
    REAL float
    TEXT зависит от text_factory , по умолчанию unicode
    BLOB buffer

    Система типов модуля sqlite3 позволяет расширяться двумя способами: возможно сохранение дополнительных типов Python в базе данных SQLite через адаптацию объектов или через преобразователи.

    Модуль sqlite3 использует адаптацию объектов Python, описанную в PEP 246. Используется протокол PrepareProtocol.

    Существует два способа настроить модуль sqlite3 для адаптации специальных типов Python.

    В примере ниже в качестве конвертируемого типа используется str, параметр protocol равен PrepareProtocol:

    class Point(object):
    def __init__(self, x, y):
    self.x, self.y = x, y

    def __conform__(self, protocol):
    if protocol is sqlite3.PrepareProtocol:
    return «%f;%f» % (self.x, self.y)

    con = sqlite3.connect( «:memory:» )
    cur = con.cursor()

    p = Point(4.0, -3.2)
    cur.execute( «select ?» , (p,))
    print cur.fetchone()[0]

    Предыдущий пример примет следующий вид:

    class Point(object):
    def __init__(self, x, y):
    self.x, self.y = x, y

    def adapt_point(point):
    return «%f;%f» % (point.x, point.y)

    con = sqlite3.connect( «:memory:» )
    cur = con.cursor()

    p = Point(4.0, -3.2)
    cur.execute( «select ?» , (p,))
    print cur.fetchone()[0]

    Модуль sqlite3 имеет по умолчанию 2 адаптера для Python типов datetime.date и datetime.datetime .
    Пример в котором объект datetime.datetime хранится не в ISO представлении, а как штамп времени UNIX:

    import sqlite3
    import datetime, time

    def adapt_datetime(ts):
    return time.mktime(ts.timetuple())

    con = sqlite3.connect( «:memory:» )
    cur = con.cursor()

    now = datetime.datetime.now()
    cur.execute( «select ?» , (now,))
    print cur.fetchone()[0]

    Интерпретация получаемых данных как типов Python модулем sqlite3 осуществляется либо неявно через объявление типов либо явно через имя столбца (использование констант PARSE_DECTYPES и PARSE_COKNAMES соответственно).
    Пример ниже раскрывает оба этих случая:

    # -*- coding: utf-8 -*-
    import sqlite3

    class Point(object):
    def __init__(self, x, y):
    self.x, self.y = x, y

    def __repr__(self):
    return «(%f;%f)» % (self.x, self.y)

    def adapt_point(point):
    return «%f;%f» % (point.x, point.y)

    def convert_point(s):
    x, y = map(float, s.split( «;» ))
    return Point(x, y)

    # Регистрируем функуию адаптер
    sqlite3.register_adapter(Point, adapt_point)

    # Регистрируем функцию конвертор
    sqlite3.register_converter( «point» , convert_point)

    #########################
    # 1) Используем объявление типа
    con = sqlite3.connect( «:memory:» , detect_types=sqlite3.PARSE_DECLTYPES)
    cur = con.cursor()
    cur.execute( «create table test(p point)» )
    cur.execute( «insert into test(p) values (?)» , (p,))
    cur.execute( «select p from test» )
    result=cur.fetchone()[0]
    print «with declared types:» , result,type(result)
    cur.close()
    con.close()

    #######################
    # 2) Используем имена столбцов
    con = sqlite3.connect( «:memory:» , detect_types=sqlite3.PARSE_COLNAMES)
    cur = con.cursor()
    cur.execute( «create table test(p)» )
    cur.execute( «insert into test(p) values (?)» , (p,))
    cur.execute( ‘select p as «p [point]» from test’ )
    result=cur.fetchone()[0]
    print «with column names:» ,result,type(result)
    cur.close()
    con.close()

    Базовые конверторы зарегистрированы под именем “date” для типа datetime.date и под именем “timestamp” для типа datetime.datetime .

    Таким образом, можно использовать даты и временные метки из Python без каких либо дополнительных махинаций в большинстве случаев. Формат адаптеров также совместим с экспериментальными функциями даты и времени SQLite.

    Пример ниже демонстрирует это:

    import sqlite3
    import datetime

    con = sqlite3.connect( «:memory:» , detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
    cur = con.cursor()
    cur.execute( «create table test(d date, ts timestamp)» )

    today = datetime.date.today()
    now = datetime.datetime.now()

    cur.execute( «insert into test(d, ts) values (?, ?)» , (today, now))
    cur.execute( «select d, ts from test» )
    row = cur.fetchone()
    print today, «=>» , row[0], type(row[0])
    print now, «=>» , row[1], type(row[1])

    cur.execute( ‘select current_date as «d [date]», current_timestamp as «ts [timestamp]»‘ )
    row = cur.fetchone()
    print «current_date» , row[0], type(row[0])
    print «current_timestamp» , row[1], type(row[1])

    Так, если Вы в пределах транзакции и даете команду как CREATE TABLE. VACUUM, PRAGMA, sqlite3 модуль будет фиксировать изменения неявно прежде, чем выполнить ту команду. Есть две причины для этого. Прежде всего, некоторые из этих команд не работают в пределах транзакций. Другая причина состоит в том, что sqlite3 должен отследить состояние транзакции (если транзакция является активной или нет).

    Вы можете контролировать какого рода выражения BEGIN выполняются (или не выполняются вовсе) неявно через параметр isolation_level при вызове connect() или через свойство соединений isolation_level.

    Если вы хотите автоматический режим фиксации изменений, то необходимо установить isolation_level в значение None .

    Иначе оставьте этот параметр по умолчанию, результатом которого будет простой оператор BEGIN или установите его в один из поддерживаемых уровней изоляций: DEFERRED, IMMEDIATE, EXCLUSIVE.

    Используя нестандартные методы execute() , executemany() и executescript() объекта Connection ваш код будет более кратким, потому что не будет явно создан объект Cursor , вместо этого он будет создан неявно и эти методы ярлыка возвращают объект курсора. Таким образом, вы можете выполнить оператор SELECT и выполнить итерации по нему используя только один вызов к объекту Connection .

    persons = [
    ( «Hugo» , «Boss» ),
    ( «Calvin» , «Klein» )]

    con = sqlite3.connect( «:memory:» )
    con.execute( «create table person(firstname, lastname)» )
    con.executemany( «insert into person(firstname, lastname) values (?, ?)» , persons)
    for row in con.execute( «select firstname, lastname from person» ):
    print row

    print «I just deleted» , con.execute( «delete from person where 1=1» ).rowcount, «rows»

    Одна из полезных возможностей модуля sqlite3 является класс sqlite3.Row разработанный что бы быть использованным как фабрика рядов.

    К рядам, обернутыми в этот класс, можно получить доступ как по индексам (подобно кортежам) так и, без влияния регистра, по имени.

    # -*- coding: utf-8 -*-
    import sqlite3

    con = sqlite3.connect( «:memory:» )
    con.row_factory = sqlite3.Row

    cur = con.cursor()
    cur.execute( «CREATE TABLE people(name_last,age)» )
    cur.execute( «INSERT INTO people values (. )» ,[( u’Степанов’ ),25])
    cur.execute( «select name_last, age from people» )
    for row in cur:
    assert row[0] == row[ «name_last» ]
    assert row[ «name_last» ] == row[ «nAmE_lAsT» ]
    assert row[1] == row[ «age» ]
    assert row[1] == row[ «AgE» ]
    print row[0],row[1]

    Объекты соединения могут использоваться в качестве менеджеров по контексту, которые автоматически фиксируют или откатывают транзакции. В случае исключения откатывается транзакция; иначе, транзакция фиксируется:

    # -*- coding: utf-8 -*-
    import sqlite3

    con = sqlite3.connect( «:memory:» )
    con.execute( «create table person (id integer primary key, firstname varchar unique)» )

    # Будет выполненно успешно, con.commit() будет вызван автоматически
    with con:
    con.execute( «insert into person(firstname) values (?)» , ( «Joe» ,))

    # con.rollback() будет вызван после блока with окончившегося исключением
    # которое должно быть перехвачено и корректно обработано
    try:
    with con:
    con.execute( «insert into person(firstname) values (?)» , ( «Joe» ,))
    except sqlite3.IntegrityError:
    print «couldn’t add Joe twice»

    Единственное исключение это вызов метода interrupt() который имеет смысл вызвать только из другого потока.

Добавить комментарий