Peewee orm манипуляция базами данных

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

Для установки соединения с базой данных существует функция 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() – используется для экранирования символов (см. документацию)

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

ORM with SqlAlchemy

An object relational mapper maps a relational database system to objects. If you are unfamiliar with object orientated programming, read this tutorial first. The ORM is independent of which relational database system is used. From within Python, you can talk to objects and the ORM will map it to the database. In this article you will learn to use the SqlAlchemy ORM.

What an ORM does is shown in an illustration below:

ORM Object Relational Mapping. We communicate with the database using the ORM and only use Python objects and classes.

Related course:

Python Programming Bootcamp: Go from zero to hero

Creating a class to feed the ORMWe create the file tabledef.py. In this file we will define a class Student. An abstract visualization of the class below:

Class definition

Observe we do not define any methods, only variables of the class. This is because we will map this class to the database and thus won’t need any methods.

This is the contents of tabledef.py:

from sqlalchemy import *from sqlalchemy import create_engine, ForeignKeyfrom sqlalchemy import Column, Date, Integer, Stringfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import relationship, backrefengine = create_engine('sqlite:///student.db', echo=True)Base = declarative_base()class Student(Base):    """"""    __tablename__ = "student"    id = Column(Integer, primary_key=True)    username = Column(String)    firstname = Column(String)    lastname = Column(String)    university = Column(String)    def __init__(self, username, firstname, lastname, university):        """"""        self.username = username        self.firstname = firstname        self.lastname = lastname        self.university = universityBase.metadata.create_all(engine)

Execute with:

python tabledef.py

The ORM created the database file tabledef.py. It will output the SQL query to the screen, in our case it showed:

CREATE TABLE student (	id INTEGER NOT NULL, 	username VARCHAR, 	firstname VARCHAR, 	lastname VARCHAR, 	university VARCHAR, 	PRIMARY KEY (id))

Thus, while we defined a class, the ORM created the database table for us. This table is still empty.

Inserting data into the databaseThe database table is still empty. We can insert data into the database using Python objects. Because we use the SqlAlchemy ORM we do not have to write a single SQL query. We now simply create Python objects that we feed to the ORM. Save the code below as dummy.py

import datetimefrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerfrom tabledef import *engine = create_engine('sqlite:///student.db', echo=True)Session = sessionmaker(bind=engine)session = Session()user = Student("james","James","Boogie","MIT")session.add(user)user = Student("lara","Lara","Miami","UU")session.add(user)user = Student("eric","Eric","York","Stanford")session.add(user)session.commit()

Execute with:

python dummy.py

The ORM will map the Python objects to a relational database. This means you do not have any direct interaction from your application, you simply interact with objects. If you open the database with SQLiteman or an SQLite database application you’ll find the table has been created:

Data in database table.

Query the dataWe can query all items of the table using the code below. Note that Python will see every record as a unique object as defined by the Students class. Save the code as demo.py

import datetimefrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerfrom tabledef import *engine = create_engine('sqlite:///student.db', echo=True)Session = sessionmaker(bind=engine)session = Session()for student in session.query(Student).order_by(Student.id):    print student.firstname, student.lastname

On execution you will see:

James BoogieLara MiamiEric York

To select a single object use the filter() method. A demonstration below:

import datetimefrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerfrom tabledef import *engine = create_engine('sqlite:///student.db', echo=True)Session = sessionmaker(bind=engine)session = Session()for student in session.query(Student).filter(Student.firstname == 'Eric'):    print student.firstname, student.lastname

Output:

Eric York

Finally, if you do not want the ORM the output any of the SQL queries change the create_engine statement to:

engine = create_engine('sqlite:///student.db', echo=False)

Обработка после инициализации

Автосгенерированный метод вызывает метод , если он определен в классе. Как правило он вызывается в форме , однако если в классе определены переменные типа , они будут переданы в качестве параметров метода.

Если метод не был сгенерирован, то он не будет вызываться.

Например, добавим сгенерированное описание книги

Параметры только для инициализации

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

SQLite query data

From console: To explore using the command line type these commands:

sqlite3 user.db.tablesSELECT * FROM Users;

This will output the data in the table Users.

sqlite> SELECT * FROM Users;1|Michelle2|Sonya3|Greg

From GUI: If you want to use a GUI instead, there is a lot of choice. Personally I picked sqllite-man but there are many others. We install using:

sudo apt-get install sqliteman

We start the application sqliteman. A gui pops up.

sqliteman

Press File > Open > user.db. It appears like not much has changed, do not worry, this is just the user interface. On the left is a small tree view, press Tables > users. The full table including all records will be showing now.

sqliteman

This GUI can be used to modify the records (data) in the table and to add new tables.

Related course:Master SQL Databases with Python

Выбор нескольких записей

Сначала выделяем категории:

Python

import peewee
from models import *

def find_all_categories():
return Category.select()

def find_all_products():
return Product.select()

1
2
3
4
5
6
7
8
9

importpeewee

frommodels import*

deffind_all_categories()

returnCategory.select()

deffind_all_products()

returnProduct.select()

Category.select() возвращает ВСЮ запись, которая будет отсортирована по столбцу created_at, что мы и указали в классе Meta.

Теперь выбираем все продукты:

Python

products = find_all_products()
product_data = []
for product in products:
product_data.append({
‘title’: product.name,
‘price’: product.price,
‘category’: product.category.name
})

print(product_data)

1
2
3
4
5
6
7
8
9
10

products=find_all_products()

product_data=

forproduct inproducts

product_data.append({

‘title’product.name,

‘price’product.price,

‘category’product.category.name

})

print(product_data)

Здесь я перебираю продукты и добавляю запись в список product_data

Обратите внимание на доступ к категории продукта. Больше нет SELECT для получения ID, с последующим поиском названия

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

Python

1
2
3
4

{‘price’24.5,’title»c++ premier’,’category»books’},

{‘price’224.25,’title»juicer’,’category»electronic appliances’}

PyMySQL заголовки столбцов

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

Python

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import pymysql

con = pymysql.connect(‘localhost’, ‘user17’,
‘s$cret’, ‘testdb’)

with con:

cur = con.cursor()
cur.execute(«SELECT * FROM cities»)

rows = cur.fetchall()

desc = cur.description

print(«{0:>3} {1:>10}».format(desc, desc))

for row in rows:
print(«{0:3} {1:>10}».format(row, row))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 

importpymysql

con=pymysql.connect(‘localhost’,’user17′,

‘s$cret’,’testdb’)

withcon

cur=con.cursor()

cur.execute(«SELECT * FROM cities»)

rows=cur.fetchall()

desc=cur.description

print(«{0:>3} {1:>10}».format(desc,desc1))

forrow inrows

print(«{0:3} {1:>10}».format(row,row2))

Названия столбцов представляют собой метаданные. Они извлекаются из объекта курсора.

Python

desc = cur.description

1 desc=cur.description

Атрибут курсора возвращает информацию о каждом результативном столбце запроса.

Python

print(«{0:>3} {1:>10}».format(desc, desc))

1 print(«{0:>3} {1:>10}».format(desc,desc1))

Таким образом, выводятся и форматируются названия столбцов таблицы.

Python

for row in rows:
print(«{0:3} {1:>10}».format(row, row))

1
2

forrow inrows

print(«{0:3} {1:>10}».format(row,row2))

Данные перебираются и выводятся на экран при помощи цикла for.

Shell

$ ./column_headers.py
id name
1 432000
2 1759000
3 1280000
4 1748000
5 3971000
6 8550000
7 464000
8 3671000

1
2
3
4
5
6
7
8
9
10

$.column_headers.py

idname

1432000

21759000

31280000

41748000

53971000

68550000

7464000

83671000

Это результат вывода.

Python NumPy

NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random
Random Intro
Data Distribution
Random Permutation
Seaborn Module
Normal Distribution
Binomial Distribution
Poisson Distribution
Uniform Distribution
Logistic Distribution
Multinomial Distribution
Exponential Distribution
Chi Square Distribution
Rayleigh Distribution
Pareto Distribution
Zipf Distribution

NumPy ufunc
ufunc Intro
ufunc Create Function
ufunc Simple Arithmetic
ufunc Rounding Decimals
ufunc Logs
ufunc Summations
ufunc Products
ufunc Differences
ufunc Finding LCM
ufunc Finding GCD
ufunc Trigonometric
ufunc Hyperbolic
ufunc Set Operations

DELETE 操作

下面的 Python 代码显示了如何使用 DELETE 语句删除任何记录,然后从 COMPANY 表中获取并显示剩余的记录:

#!/usr/bin/python

import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
print "Opened database successfully"

c.execute("DELETE from COMPANY where ID=2;")
conn.commit()
print "Total number of rows deleted :", conn.total_changes

cursor = conn.execute("SELECT id, name, address, salary  from COMPANY")
for row in cursor:
   print "ID = ", row
   print "NAME = ", row
   print "ADDRESS = ", row
   print "SALARY = ", row, "\n"

print "Operation done successfully"
conn.close()

上述程序执行时,它会产生以下结果:

Opened database successfully
Total number of rows deleted : 1
ID =  1
NAME =  Paul
ADDRESS =  California
SALARY =  20000.0

ID =  3
NAME =  Teddy
ADDRESS =  Norway
SALARY =  20000.0

ID =  4
NAME =  Mark
ADDRESS =  Rich-Mond
SALARY =  65000.0

Operation done successfully

PyMySQL — узнаем версию MySQL

В следующем примере показано, как отобразить текущую версию MySQL.

Python

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import pymysql

con = pymysql.connect(‘localhost’, ‘user17’,
‘s$cret’, ‘mydb’)

with con:

cur = con.cursor()
cur.execute(«SELECT VERSION()»)

version = cur.fetchone()

print(«Database version: {}».format(version))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#!/usr/bin/python3
# -*- coding: utf-8 -*-
 

importpymysql

con=pymysql.connect(‘localhost’,’user17′,

‘s$cret’,’mydb’)

withcon

cur=con.cursor()

cur.execute(«SELECT VERSION()»)

version=cur.fetchone()

print(«Database version: {}».format(version))

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

Python

import pymysql

1 importpymysql

Для этого потребуется импортировать модуль.

Python

con = pymysql.connect(‘localhost’, ‘user17’,
‘s$cret’, ‘mydb’)

1
2

con=pymysql.connect(‘localhost’,’user17′,

‘s$cret’,’mydb’)

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

  • имя хоста;
  • имя пользователя;
  • пароль;
  • название базы данных.

Python

with con:

1 withcon

При помощи интерпретатор Python автоматически открывает доступные ресурсы. Он также обрабатывает возможные ошибки.

Python

cur = con.cursor()

1 cur=con.cursor()

Из объекта подключения создается курсор. Курсор используется для перемещения записей из набора результатов.

Python

cur.execute(«SELECT VERSION()»)

1 cur.execute(«SELECT VERSION()»)

Для использования команды SQL вызывается метод курсора .

Python

version = cur.fetchone()

1 version=cur.fetchone()

Метод позволяет вызвать следующую строку из набора результатов запроса, показывая только одну запись. В том случае, если доступных данных нет, выводится .

Python

print(«Database version: {}».format(version))

1 print(«Database version: {}».format(version))

Таким образом, версия базы данных выводится на экран.

Shell

$ ./version.py
Database version: 5.7.23-0ubuntu0.16.04.1

1
2

$.version.py

Database version5.7.23-0ubuntu0.16.04.1

Это результат вывода.

UPDATE Operation

Following Python code shows how to use UPDATE statement to update any record and then fetch and display the updated records from the COMPANY table.

#!/usr/bin/python

import sqlite3

conn = sqlite3.connect('test.db')
print "Opened database successfully";

conn.execute("UPDATE COMPANY set SALARY = 25000.00 where ID = 1")
conn.commit()
print "Total number of rows updated :", conn.total_changes

cursor = conn.execute("SELECT id, name, address, salary from COMPANY")
for row in cursor:
   print "ID = ", row
   print "NAME = ", row
   print "ADDRESS = ", row
   print "SALARY = ", row, "\n"

print "Operation done successfully";
conn.close()

When the above program is executed, it will produce the following result.

Opened database successfully
Total number of rows updated : 1
ID = 1
NAME = Paul
ADDRESS = California
SALARY = 25000.0

ID = 2
NAME = Allen
ADDRESS = Texas
SALARY = 15000.0

ID = 3
NAME = Teddy
ADDRESS = Norway
SALARY = 20000.0

ID = 4
NAME = Mark
ADDRESS = Rich-Mond
SALARY = 65000.0

Operation done successfully

Вставка записи (INSERT)

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

Python

import peewee
from models import *

def add_category(name):
row = Category(
name=name.lower().strip(),
)
row.save()

add_category(‘Books’)

1
2
3
4
5
6
7
8
9
10

importpeewee

frommodels import*

defadd_category(name)

row=Category(

name=name.lower().strip(),

)

row.save()

add_category(‘Books’)

Я добавил функцию под названием add_category() с параметром и именем внутри. Объект Category создан, как и поля таблицы, которые являются переданной собственностью данного объекта класса. В нашем случае, это поле name.

The row.save() сохраняет данные из объекта в базу данных.

Круто, не так ли? Больше не нужно прописывать уродливые INSERT-ы.

Теперь добавим product.

Python

import peewee
from models import *

def add_product(name, price, category_name):
cat_exist = True
try:
category = Category.select().where(Category.name == category_name.strip()).get()
except DoesNotExist as de:
cat_exist = False

if cat_exist:
row = Product(
name=name.lower().strip(),
price=price,
category=category
)
row.save()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

importpeewee

frommodels import*

defadd_product(name,price,category_name)

cat_exist=True

try

category=Category.select().where(Category.name==category_name.strip()).get()

exceptDoesNotExist asde

cat_exist=False

ifcat_exist

row=Product(

name=name.lower().strip(),

price=price,

category=category

)

row.save()

add_product берет name, price и category_id в качестве вводных данных. Сначала, я проверю, существует ли категория, если да – значит её объекты хранятся в базе. В ORM вы имеете дело с объектом, по этому вы передаете информацию о категории в качестве объекта, так как мы уже определили эту взаимосвязь ранее.

Далее, я буду создавать разделы в main.py:

Python

add_category(‘Books’)
add_category(‘Electronic Appliances’)

1
2

add_category(‘Books’)

add_category(‘Electronic Appliances’)

Теперь добавим продукты:

Python

# Добавление продуктов.
add_product(‘C++ Premier’, 24.5, ‘books’)
add_product(‘Juicer’, 224.25, ‘Electronic Appliances’)

1
2
3

# Добавление продуктов.

add_product(‘C++ Premier’,24.5,’books’)

add_product(‘Juicer’,224.25,’Electronic Appliances’)

Полный main.py можете видеть ниже:

main.py

Python

import peewee
from models import *

def add_category(name):
row = Category(
name=name.lower().strip(),
)
row.save()

def add_product(name, price, category_name):
cat_exist = True
try:
category = Category.select().where(Category.name == category_name.strip()).get()
except DoesNotExist as de:
cat_exist = False

if cat_exist:
row = Product(
name=name.lower().strip(),
price=price,
category=category
)
row.save()

if __name__ == ‘__main__’:
# Создаем разделы.
add_category(‘Books’)
add_category(‘Electronic Appliances’)

# Добавляем продукты в разделы.
add_product(‘C++ Premier’, 24.5, ‘books’)
add_product(‘Juicer’, 224.25, ‘Electronic Appliances’)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

importpeewee

frommodels import*

defadd_category(name)

row=Category(

name=name.lower().strip(),

)

row.save()

defadd_product(name,price,category_name)

cat_exist=True

try

category=Category.select().where(Category.name==category_name.strip()).get()

exceptDoesNotExist asde

cat_exist=False

ifcat_exist

row=Product(

name=name.lower().strip(),

price=price,

category=category

)

row.save()

if__name__==’__main__’

# Создаем разделы.

add_category(‘Books’)

add_category(‘Electronic Appliances’)

# Добавляем продукты в разделы.

add_product(‘C++ Premier’,24.5,’books’)

add_product(‘Juicer’,224.25,’Electronic Appliances’)

Я передаю имя категории, как только её объект будет найден и передан объекту класса Product. Если вы хотите пойти по пути SQL, для начала вам нужно выполнить SELECT, чтобы получить существующий category_id, и затем назначить id добавляемому продукту.

Так как работать с ORM – значит иметь дело с объектами, мы храним объекты вместо скалярных значений. Кто-то может посчитать это слишком «инженерным» методом в нашем случае, но подумайте о случаях, когда вы понятия не имеете о том, какая база данных должна быть использована в будущем. Ваш код – это универсальный инструмент для работы с базами данных, так что если он работает с MySQL, или MSSQL, то он будет работать даже с MongoDb (гипотетически).

Connection methods

Close the connection now (rather than whenever .__del__() is
called).

The connection will be unusable from this point forward; an
(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. Note that closing a
connection without committing the changes first will cause an
implicit rollback to be performed.

()

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.

()

This method is optional since not all databases provide transaction
support.

In case a database does provide transactions this method causes 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 модуля MySQLdb поддерживает итерации. Это значит, что можно обойти все записи в наборе данных полученных из cur.execute без использования метода cur.fetchall, а просто используя инструкцию for row in cur:

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

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

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

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

Bulk inserts¶

If you have more than one record to insert, the method is a much more efficient way of inserting them. Just like it will automatically detect the columns that should be created, but it will inspect the first batch of 100 items to help decide what those column types should be.

Use it like this:

dogs.insert_all(, pk="id", column_order=("id", , "name"))

The column types used in the statement are automatically derived from the types of data in that first batch of rows. Any additional columns in subsequent batches will cause a exception to be raised unless the argument is supplied, in which case the new columns will be created.

The function can accept an iterator or generator of rows and will commit them according to the batch size. The default batch size is 100, but you can specify a different size using the parameter:

db"big_table".insert_all(({
    "id" 1,
    "name" "Name {}".format(i),
} for i in range(10000)), batch_size=1000)

You can skip inserting any records that have a primary key that already exists using . This works with both and .

Функции, которые пригодятся позже

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

open

Эта функция служит для открытия файла и последующей работы с ним. Но, если вы не работаете с файлами напрямую, то она вам может и не пригодиться.

Несмотря на то, что работа с файлами очень распространена, далеко не все программисты Python работают с файлами через . Например, разработчики Django могут не использовать её вообще.

input

Эта функция запрашивает у пользователя ввод, ждёт нажатия клавиши Enter, а затем возвращает набранный текст.

Чтение из стандартного ввода — это один из способов получить входные данные в программе. Но есть и много других способов: аргументы командной строки, чтение из файла, чтение из базы данных и многое другое.

repr

Эта функция необходима для представления объекта в читабельном виде.

Для многих объектов функции и работают одинаково.

Но есть объекты, для которых их применение различается.

Строковое представление, которое вы видите в Python Shell, использует , тогда как функция использует .

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

super

Эта функция очень важна, если используется наследование одного класса от другого.

Многие пользователи Python редко создают классы

Они не являются важной частью Python, хоть для многих типов программирования они необходимы. Например, вы не можете использовать веб-фреймворк Django без создания классов

property

Эта функция является и .

Декоратор позволяет создать атрибут, который всегда будет содержать возвращаемое значение конкретного вызова функции. Это проще всего понять на примере.

Пример класса, который использует .

Здесь вы можете увидеть доступ к атрибуту объекта .

Если вы занимаетесь объектно-ориентированным программированием на Python, вам, вероятно, захочется узнать о больше в какой-то момент. В отличие от других объектно-ориентированных языков, в Python используется вместо методов и .

issubclass и isinstance

Функция проверяет, является ли класс подклассом одного или нескольких других классов.

Функция проверяет, является ли объект экземпляром одного или нескольких классов.

Функция может быть представлена как делегирование в .

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

hasattr, getattr, setattr и delattr

Если нужно работать с атрибутами объекта, но имя атрибутов является динамическим и постоянно меняется, данные функции вам будут необходимы.

Например, есть объект , который нужно проверить на конкретное значение.

Функция позволяет проверить, имеет ли объект определённый атрибут.

Функция позволяет получить значение атрибута (с необязательным значением по умолчанию, если атрибут не существует).

Функция позволяет установить значение атрибута.

И соответственно удаляет атрибут.

classmethod и staticmethod

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

Немного сложнее придумать хорошее использование , так как всегда можно использовать функцию уровня модуля вместо статического метода.

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

next

Данная функция возвращает следующий элемент в итераторе.

Она может работать со следующими видами итераторов:

  • объекты ;
  • объекты ;
  • возвращаемые значения функции ;
  • файлы
  • объекты ;
  • генератор-выражения;
  • генератор-функции;

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

Introspection¶

If you have loaded an existing table or view, you can use introspection to find out more about it:

>>> db"PlantType"
<Table PlantType (id, value)>

The method can be used to find out if a table exists or not:

>>> db"PlantType".exists()
True
>>> db"PlantType2".exists()
False

The property shows the current number of rows ():

>>> db"PlantType".count
3
>>> db"Street_Tree_List".count
189144

The property shows the columns in the table or view:

>>> db"PlantType".columns

The property returns a dictionary version of this with just the names and types:

>>> db"PlantType".columns_dict
{'id': <class 'int'>, 'value': <class 'str'>}

The property returns a list of strings naming the primary key columns for the table:

>>> db"PlantType".pks

The property shows if the table has any foreign key relationships. It is not available on views.

>>> db"Street_Tree_List".foreign_keys

The property outputs the table’s schema as a SQL string:

>>> print(db"Street_Tree_List".schema)
CREATE TABLE "Street_Tree_List" (
"TreeID" INTEGER,
  "qLegalStatus" INTEGER,
  "qSpecies" INTEGER,
  "qAddress" TEXT,
  "SiteOrder" INTEGER,
  "qSiteInfo" INTEGER,
  "PlantType" INTEGER,
  "qCaretaker" INTEGER,
  "qCareAssistant" INTEGER,
  "PlantDate" TEXT,
  "DBH" INTEGER,
  "PlotSize" TEXT,
  "PermitNotes" TEXT,
  "XCoord" REAL,
  "YCoord" REAL,
  "Latitude" REAL,
  "Longitude" REAL,
  "Location" TEXT
,
FOREIGN KEY ("PlantType") REFERENCES (id),
    FOREIGN KEY ("qCaretaker") REFERENCES (id),
    FOREIGN KEY ("qSpecies") REFERENCES (id),
    FOREIGN KEY ("qSiteInfo") REFERENCES (id),
    FOREIGN KEY ("qCareAssistant") REFERENCES (id),
    FOREIGN KEY ("qLegalStatus") REFERENCES (id))

The property shows you all indexes created for a table. It is not available on views.

>>> db"Street_Tree_List".indexes
),
 Index(seq=1, name='"Street_Tree_List_qCareAssistant"', unique=0, origin='c', partial=0, columns=),
 Index(seq=2, name='"Street_Tree_List_qSiteInfo"', unique=0, origin='c', partial=0, columns=),
 Index(seq=3, name='"Street_Tree_List_qSpecies"', unique=0, origin='c', partial=0, columns=),
 Index(seq=4, name='"Street_Tree_List_qCaretaker"', unique=0, origin='c', partial=0, columns=),
 Index(seq=5, name='"Street_Tree_List_PlantType"', unique=0, origin='c', partial=0, columns=)]

The property lists database triggers. It can be used on both database and table objects.

>>> db"authors".triggers
 AFTER INSERT...'),
 Trigger(name='authors_ad', table='authors', sql="CREATE TRIGGER  AFTER DELETE..."),
 Trigger(name='authors_au', table='authors', sql="CREATE TRIGGER  AFTER UPDATE")]
>>> db.triggers
... similar output to db"authors".triggers

The method returns the associated SQLite FTS table name, if one exists for this table. If the table has not been configured for full-text search it returns .

Как создавать базу данных и вставлять различные данные

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

Python

import sqlite3

conn = sqlite3.connect(«mydatabase.db») # или :memory: чтобы сохранить в RAM
cursor = conn.cursor()

# Создание таблицы
cursor.execute(«»»CREATE TABLE albums
(title text, artist text, release_date text,
publisher text, media_type text)
«»»)

1
2
3
4
5
6
7
8
9
10

importsqlite3

conn=sqlite3.connect(«mydatabase.db»)# или :memory: чтобы сохранить в RAM

cursor=conn.cursor()

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

cursor.execute(«»»CREATE TABLE albums

                  (title text, artist text, release_date text,
                   publisher text, media_type text)

               «»»)

Сначала нам нужно импортировать модуль sqlite3 и создать связь с базой данных. Вы можете передать название файла или просто использовать специальную строку “:memory:” для создания базы данных в памяти. В нашем случае, мы создаем его на диске в файле под названием mydatabase.db.

Далее мы создаем объект cursor, который позволяет нам взаимодействовать с базой данных и добавлять записи, помимо всего прочего. Здесь мы используем синтаксис SQL для создания таблицы под названием альбомы с пятью следующими полями: title, artist, release_date, publisher и media_type. SQLite поддерживает только пять типов данных: null, integer, real, text и blob. Давайте напишем этот код и вставим кое-какие данные в нашей новой таблице. Запомните, если вы запускаете команду CREATE TABLE, при этом база данных уже существует, вы получите сообщение об ошибке.

Python

# Вставляем данные в таблицу
cursor.execute(«»»INSERT INTO albums
VALUES (‘Glow’, ‘Andy Hunter’, ‘7/24/2012’,
‘Xplore Records’, ‘MP3’)»»»
)

# Сохраняем изменения
conn.commit()

# Вставляем множество данных в таблицу используя безопасный метод «?»
albums = [(‘Exodus’, ‘Andy Hunter’, ‘7/9/2002’, ‘Sparrow Records’, ‘CD’),
(‘Until We Have Faces’, ‘Red’, ‘2/1/2011’, ‘Essential Records’, ‘CD’),
(‘The End is Where We Begin’, ‘Thousand Foot Krutch’, ‘4/17/2012’, ‘TFKmusic’, ‘CD’),
(‘The Good Life’, ‘Trip Lee’, ‘4/10/2012’, ‘Reach Records’, ‘CD’)]

cursor.executemany(«INSERT INTO albums VALUES (?,?,?,?,?)», albums)
conn.commit()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Вставляем данные в таблицу

cursor.execute(«»»INSERT INTO albums

                  VALUES (‘Glow’, ‘Andy Hunter’, ‘7/24/2012’,
                  ‘Xplore Records’, ‘MP3’)»»»

)

 
# Сохраняем изменения

conn.commit()

 
# Вставляем множество данных в таблицу используя безопасный метод «?»

albums=(‘Exodus’,’Andy Hunter’,’7/9/2002′,’Sparrow Records’,’CD’),

(‘Until We Have Faces’,’Red’,’2/1/2011′,’Essential Records’,’CD’),

(‘The End is Where We Begin’,’Thousand Foot Krutch’,’4/17/2012′,’TFKmusic’,’CD’),

(‘The Good Life’,’Trip Lee’,’4/10/2012′,’Reach Records’,’CD’)

cursor.executemany(«INSERT INTO albums VALUES (?,?,?,?,?)»,albums)

conn.commit()

Здесь мы использовали команду INSERT INTO SQL чтобы вставить запись в нашу базу данных

Обратите внимание на то, что каждый объект находится в одинарных кавычках. Это может усложнить работу, если вам нужно вставить строчки, которые содержат одинарные кавычки

В любом случае, чтобы сохранить запись в базе данных, нам нужно создать её. Следующая часть кода показывает, как добавить несколько записей за раз при помощи метода курсора executemany. Обратите внимание на то, что мы используем знаки вопроса (?), вместо строк замещения (%) чтобы вставить значения. Обратите внимание, что использование строки замещения не безопасно, так как может стать причиной появления атаки инъекций SQL . Использование знака вопроса намного лучше, а использование SQLAlchemy тем более, так как он делаете все необходимое, чтобы уберечь вас от правки встроенных одинарных кавычек на то, что SQLite в состоянии принимать.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *