Работа с базой.
Django ORM

Александр Бекбулатов
Где хранить данные
На клиенте
• Cookie (до 4Кб)
• HTML5 Web Storage (до 5Мб)

На сервере
• В памяти
• На диске
• На диске и в памяти
2
Работа с базой

1. Представление о СУБД
2. Проектирование баз данных
3. Основные операции SQL

4. Работа с базами данных в python
5. Работа с базами данных в django

3
Представление о СУБД
База данных
взаимосвязанная информация (данные) об

объектах, которая организованна специальным
образом и хранится на каком-либо носителе.
СУБД

совокупность программных и лингвистических
средств общего или специального назначения,
обеспечивающих управление созданием и
использованием баз данных.
4
Представление о СУБД
Функции СУБД
 управление данными на дисках и в оперативной памяти
 журнализация изменений, резервное копирование и
восстановление базы данных после сбоев;
 поддержка языков БД (язык определения данных, язык
манипулирования данными).

5
Реляционная модель данных
 Таблица – отношение, relation
 Строка – кортеж, tuple
 Столбец – атрибут, column

Car
Key
1
2
3

Model
Toyota Camry
Audi A4
Honda Civic

Color
Key
1
2

Color
1
2
2

Name
Black
Pink

Year
2010
2013
2013
6
Реляционная модель данных
Cousine
Key
1
2

Ingredient
Key
1
2
3

Name
Baked fish
Pork Chops

Name
Pork
Lamb
Salmon

Type
Main Course
Main Course
CousineIngredient
CousineKey
IngredientKey
1
3
2
1

7
Реляционная модель данных
Задачи проектирования
 Обеспечение хранения в БД всей необходимой информации.

 Обеспечение возможности получения данных по всем
необходимым запросам.
 Сокращение избыточности и дублирования данных.
 Обеспечение целостности данных (правильности их
содержания): исключение противоречий в содержании данных,
исключение их потери и т.д.

8
Реляционная модель данных
Проектирование на практике
 Логическое разделение сущностей

 Выделение синтетических первичных ключей
 Связи 1:N, N:1 реализуются через внешний ключ

 Связи N:M реализуются через промежуточную таблицу
 Атрибут с фиксированным числом значений – внешняя
таблица либо поле типа enum

9
Основные операции SQL

10
SELECT
SELECT * FROM users WHERE age > 10;
SELECT * FROM users WHERE name = 'masha';
SELECT max(age) FROM users;
SELECT id, name, length(name) AS len
FROM users
WHERE email LIKE '%@mail.ru' AND age > 10
ORDER BY name DESC
LIMIT 10 OFFSET 15

11
SELECT. Агрегация
Агрегатные функции:
COUNT, SUM, AVG, GROUP_CONCAT
SELECT name, count(id) cnt
FROM users
GROUP BY name
ORDER BY cnt
HAVING cnt > 1

12
SELECT. JOIN
SELECT h.name, a.name
FROM heroes h, abilities a
WHERE h.id = a.hero_id
SELECT h.name, a.name
FROM heroes h
INNER JOIN abilities a ON h.id = a.hero_id

SELECT h.name, a.name
FROM heroes h
LEFT JOIN abilities a ON h.id = a.hero_id

13
SELECT. Вложенные запросы
SELECT title
FROM article t1
JOIN (
SELECT rubric_id, MAX(id) max_id
FROM article
GROUP BY rubric_id LIMIT 5
) t2
ON t1.id = t2.max_id;

14
INSERT, UPDATE, DELETE
INSERT INTO users (name, age) VALUES ('Petr', 10);
UPDATE users SET age = 20 WHERE name = 'Petr';
UPDATE users SET rating = rating + 1;
DELETE FROM users WHERE name = 'Masha';
DELETE FROM users WHERE age > 150;

15
Индексы
Проектирование на практике
 Создавать индексы для полей, по которым происходит JOIN
 Создавать индексы для полей, по которым фильтруются
записи (WHERE)
 Создавать индексы для полей, по которым идет сортировка
(ORDER)
 Проверять план выполнения запроса (EXPLAIN)
 Управление оптимизатором (принудительное использование
индекса, порядок соединения таблиц)

16
Работа с базами данных в

python

17
MySQLdb
import MySQLdb
db = MySQLdb.connect(
host="localhost", user="joebob",
passwd="moonpie", db="thangs")
cursor = db.cursor()

18
MySQLdb
cursor.execute('update users set age = age + 1
where name = %s', (name,))
cursor.execute('select * from users')
users = cursor.fetchall()
cursor.execute('select * from users where name =
%s', (name,))
user = cursor.fetchone()

19
MySQLdb
cursor.executemany(
"INSERT INTO users (name, age) VALUES (%s,
%s)",
[
("Igor", 18 ),
("Petr", 16 ),
("Dasha", 17 )
])

db.close()

20
MySQLdb
Зачем плейсхолдеры?
email = "' OR '1'='1"
cursor.execute("SELECT * FROM users WHERE email =
'%s'" % email)

Документация
http://mysql-python.sourceforge.net/MySQLdb.html

21
Работа с базами данных в

django

22
Классы в Python
class Employee(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
def __unicode__(self):
return unicode(self.name)
def get_info(self):
return "Name : %s, Salary: %s" % (self.name,
self.salary)
class Programmer(Employee):
def __init__(self, name, salary, lang):
super(Programmer, self).__init__(name,
salary)
self.lang = lang
23
Классы в Python
>>> e1 = Programmer(u'Vasya', 100, 'VB')
>>> print u'Welcome %s' % e1
Welcome Vasya
>>> e1.get_info()
u'Name : Vasya, Salary: 100'
>>> e1.lang
'VB'

24
Raw SQL vs ORM
cursor.execute('select * from users where age >
18')
for user in cursor.fetchall():
pk, name, age = user
print name
VS

for user in User.objects.filter(age__gt=18):
print user.name

25
Модели и типы данных
class Post(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
creation_date =
models.DateTimeField(default=datetime.datetime.now)

def __unicode__(self):
return self.title
def get_absolute_url(self):
return '/post/%d/' % self.pk
def get_next_post(self):
"""Return the next entry"""
class Meta:
ordering = ['-creation_date’]

26
Модели и типы данных

Типы данных Mysql
varchar(N)

longtext
tinyint(1)
int(11)
smallint(5) unsigned
date
datetime

Типы полей Django
CharField
EmailField
SlugField
ImageField
TextField
BooleanField
IntegerField
PositiveSmallIntegerField
DateField
DateTimeField
27
Модели и типы данных
Свойства полей моделей
null, blank, choices, db_index, default, editable,
help_text, max_length, primary_key, unique, unique_for_date,
unique_for_month, unique_for_year, verbose_name
https://docs.djangoproject.com/en/dev/ref/models/fields/

28
Связи между таблицами
class Post(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
creation_date =
models.DateTimeField(default=datetime.datetime.now)
category = models.ForeignKey(Category,
on_delete=models.SET_NULL)
tags = models.ManyToManyField(Tag)

29
Связи между таблицами
ForeignKey, OneToOneField
ForeignKey = IntegerField + Constraint
OneToOneField = ForeignKey + unique
post.category – связанный объект (отдельный запрос к
связанной сущности)
post.category_id – значение атрибута модели (просто id)
В обратную сторону:
category.post_set.all()
30
Связи между таблицами
ForeignKey, OneToOneField
Изменение/удаление внешнего ключа
•
•
•
•

RESTRICT -> models.PROTECT
CASCADE -> models.CASCADE
SET NULL -> models.SET_NULL
NO ACTION -> models.DO_NOTHING

31
Связи между таблицами
ManyToManyField

Tag
id
title
description

Post
id
title
content
creation_date
category
PostTag

post_id
tag_id

32
Связи между таблицами
ManyToManyField
post.tags – related manager
post.tags.all()
В обратную сторону:
tag.post_set.all()

33
ORM API
python manage.py shell
>>> from blog.models import Category, Post
>>> from django.db import connection

>>> # Вставка и замена
>>>
>>>
>>>
1
>>>
>>>

c = Category(title="Python")
c.save()
c.id
c.title="About Python"
c.save()

34
ORM API
python manage.py shell
>>> print 'n'.join(q['sql'] for q in
connection.queries)

INSERT INTO `blog_category` (`title`,
`description`) VALUES ('Python', '')
SELECT (1) AS `a` FROM `blog_category` WHERE
`blog_category`.`id` = 1 LIMIT 1
UPDATE `blog_category` SET `title` = 'About
Python', `description` = '' WHERE
`blog_category`.`id` = 1
35
ORM API
>>> # Выборка
>>> Category.objects.all()
[<Category: About Python>]
>>> print Category.objects.all().query
SELECT `blog_category`.`id`,
`blog_category`.`title`,
`blog_category`.`description` FROM `blog_category`
>>> Category.objects.filter(id=1)
[<Category: About Python>]
>>> c = Category.objects.get(id=1)
>>> c
<Category: About Python>
>>> c.post_set.all()
[]
36
ORM API
>>> c.post_set.create(title="New post",
content="Many words")
<Post: New post>
>>> c.post_set.count()
1
>>> p = Post.objects.get(title="New post")
>>> p.category
<Category: About Python>
>>> p.category_id
1
>>> Post.objects.filter(category__title="About
Python")
<Post: New post>
>>> c.delete()
37
Debug Toolbar
https://github.com/django-debugtoolbar/django-debug-toolbar

38
Manager и RelatedManager
Методы Manager
 slice [10:20]
 .all(), .filter(), .exclude(), .order_by()
 .values(), .values_list()
 .get(), .get_or_create(), .count(), .exists()
 .select_related(), .prefetch_related()
 .update(), .delete()

39
Manager и RelatedManager
Методы RelatedManager
 .create(**kwargs)
 .add(obj1[, obj2, ...])
 .remove(obj1[, obj2, ...])
 .clear()

40
Особенности QuerySet
Queryset ленивый
qs = Category.objects.all()
if not user.is_admin:
qs = qs.filter(active=True)
print qs.count()

41
Особенности QuerySet
Избегайте лишних запросов в базу
Foreign key кешируется
post.category

Queryset – нет.
Если нужно использовать несколько раз – кешируйте явно
question_list = list(Question.objects.all())

42
Особенности QuerySet
Атомарное обновление
Question.objects.filter(pk=10) 
.update(rating=models.F('rating') + 1)

https://docs.djangoproject.com/en/dev/ref/models/querysets/

43
Создание базы
CREATE DATABASE ask_db CHARACTER SET utf8
COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON ask_db.* TO
ask_user@localhost identified BY 'secret';

44
Подключение базы
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ask_db',
'USER': 'ask_user',
'PASSWORD': 'secret',
'HOST': '',
'PORT': '',
}
}

45
Полезные команды
 Проверка моделей
python manage.py validate
 Вывод SQL
python manage.py sqlall <app_name>
 Выполнение SQL в базе
python manage.py syncdb

46
SQL. Создание таблиц
CREATE TABLE `blog_post` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`title` varchar(255) NOT NULL,
`content` longtext NOT NULL,
`creation_date` datetime NOT NULL,
`category_id` integer NOT NULL
)
;
ALTER TABLE `blog_post` ADD CONSTRAINT
`category_id_refs_id_e0428883` FOREIGN KEY
(`category_id`) REFERENCES `blog_category` (`id`);
ALTER TABLE `blog_post_tags` ADD CONSTRAINT
`post_id_refs_id_c9e37cca` FOREIGN KEY (`post_id`)
REFERENCES `blog_post` (`id`);
CREATE INDEX `blog_post_42dc49bc` ON `blog_post`
(`category_id`);
47
SQL. Удаление и изменение таблиц
DROP TABLE blog_post;
ALTER TABLE users ADD COLUMN language
enum('ru', 'en') NOT NULL DEFAULT 'ru' after
name;
ALTER TABLE users DROP COLUMN langauge;
ALTER TABLE users ADD INDEX ('name');
ALTER TABLE users CHANGE nickname fullname
varchar(255) NOT NULL;
48
Миграции

1. DROP DATABASE, CREATE DATABASE
2. DROP TABLE, CREATE TABLE
3. ALTER TABLE

4. South

49
South

• Автоматическое создание миграций
• Поддержка различных СУБД
• Прямые и обратные миграции

50
South Workflow
1. Создать миграцию
./manage.py schemamigration ask --initial

2. Применить миграцию
./manage.py migrate ask

3. Изменить модель
4. Создать миграцию
./manage.py schemamigration ask --auto

5. Применить миграцию
./manage.py migrate ask
51
1. MySQL http://dev.mysql.com/doc/refman/5.5/en/index.html
2. Mysqldb http://mysql-python.sourceforge.net/MySQLdb.html

3. Django http://docs.djangoproject.com/en/dev/
4. Django Debug Toolbar https://github.com/django-debugtoolbar/django-debug-toolbar

52
1. Установить Django Debug Toolbar
2. Установить MySQL, python-mysqldb. Создать базу данных и
пользователя для работы с базой
3. Описать модели для проекта «Вопросы и ответы»
4. Наполнить базу тестовыми данными

53
Спасибо за внимание
Александр Бекбулатов,
a.bekbulatov@corp.mail.ru

More Related Content

PPTX
Web осень 2013 лекция 7
PPTX
Web осень 2013 лекция 8
PPTX
Web осень 2013 лекция 9
PPTX
Web осень 2013 лекция 4
PPTX
Web осень 2013 лекция 5
PDF
Web осень 2013 лекция 2
PDF
Web осень 2013 лекция 3
PDF
Web осень 2013 лекция 1
Web осень 2013 лекция 7
Web осень 2013 лекция 8
Web осень 2013 лекция 9
Web осень 2013 лекция 4
Web осень 2013 лекция 5
Web осень 2013 лекция 2
Web осень 2013 лекция 3
Web осень 2013 лекция 1

What's hot (20)

PDF
Лекция #5. Введение в язык программирования Python 3
PPTX
Максим Щепелин. "Unittesting. Как?"
PPTX
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
PDF
Профилирование и отладка Django
PPT
Производительность в Django
PPT
Эффективное программирование на NodeJS
PDF
11 - Web-технологии. Работа с СУБД
PPT
PHP Tricks
PPTX
Взломать сайт на ASP.NET
DOC
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)
PPT
CC HackQuest 2010 Full Disclosure (мастер-класс)
PPTX
Тестирование программных фильтров безопасности
KEY
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
PPTX
тестирование защищенности веб приложений
PDF
Лекция 9. Модули, пакеты и система импорта.
PDF
Лекция 2. Всё, что вы хотели знать о функциях в Python.
PDF
Магия в Python: Дескрипторы. Что это?
PPT
PDF
Лекция 13. Многопоточность и GIL
PDF
JavaScript Базовый. Занятие 07.
Лекция #5. Введение в язык программирования Python 3
Максим Щепелин. "Unittesting. Как?"
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
Профилирование и отладка Django
Производительность в Django
Эффективное программирование на NodeJS
11 - Web-технологии. Работа с СУБД
PHP Tricks
Взломать сайт на ASP.NET
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)
CC HackQuest 2010 Full Disclosure (мастер-класс)
Тестирование программных фильтров безопасности
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
тестирование защищенности веб приложений
Лекция 9. Модули, пакеты и система импорта.
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Магия в Python: Дескрипторы. Что это?
Лекция 13. Многопоточность и GIL
JavaScript Базовый. Занятие 07.
Ad

Similar to Web осень 2013 лекция 6 (20)

PPTX
django-and-postgresql
PDF
Лекция #7. Django ORM
PDF
SQL. Django, начало
PDF
Лекция 6: Работа с данными. Django ORM
PPTX
C++ и базы данных
PPTX
СУБД 2013 Лекция №1 "Введение и начало проектирования"
PPTX
Стажировка-2013, разработчики, занятие 11. Базы данных
PPTX
MySQL® и MongoDB® - когда что лучше использовать? / Петр Зайцев (Percona)
PPTX
Управление Данными. Лекция 1
PPT
Web осень 2012 лекция 4
DOCX
бд шпора2
PDF
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
PDF
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
PDF
12 - Web-технологии. Django модели
PPTX
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 08
PPT
Web весна 2013 лекция 4
PDF
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
PPT
Django шахрай. версия 4
django-and-postgresql
Лекция #7. Django ORM
SQL. Django, начало
Лекция 6: Работа с данными. Django ORM
C++ и базы данных
СУБД 2013 Лекция №1 "Введение и начало проектирования"
Стажировка-2013, разработчики, занятие 11. Базы данных
MySQL® и MongoDB® - когда что лучше использовать? / Петр Зайцев (Percona)
Управление Данными. Лекция 1
Web осень 2012 лекция 4
бд шпора2
То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Доклад Сергея Аверина на CodeFest-2013. "MySQL+HandlerSocket=NoSQL".
12 - Web-технологии. Django модели
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 08
Web весна 2013 лекция 4
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Django шахрай. версия 4
Ad

More from Technopark (20)

PDF
Лекция 11. Вычислительная модель Pregel
PDF
Лекция 14. Hadoop в Поиске Mail.Ru
PDF
Лекция 13. YARN
PDF
Лекция 12. Spark
PDF
Лекция 10. Apache Mahout
PDF
Лекция 9. ZooKeeper
PDF
Лекция 7. Введение в Pig и Hive
PDF
Лекция 6. MapReduce в Hadoop (графы)
PDF
Лекция 5. MapReduce в Hadoop (алгоритмы)
PDF
Лекция 4. MapReduce в Hadoop (введение)
PDF
Лекция 3. Распределённая файловая система HDFS
PDF
Лекция 2. Основы Hadoop
PDF
Лекция 1. Введение в Big Data и MapReduce
PPTX
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"
PPT
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...
PPTX
СУБД 2013 Лекция №9 "Безопасность баз данных"
PPTX
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
PPTX
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"
PPTX
СУБД 2013 Лекция №5 "Определение узких мест"
PPTX
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
Лекция 11. Вычислительная модель Pregel
Лекция 14. Hadoop в Поиске Mail.Ru
Лекция 13. YARN
Лекция 12. Spark
Лекция 10. Apache Mahout
Лекция 9. ZooKeeper
Лекция 7. Введение в Pig и Hive
Лекция 6. MapReduce в Hadoop (графы)
Лекция 5. MapReduce в Hadoop (алгоритмы)
Лекция 4. MapReduce в Hadoop (введение)
Лекция 3. Распределённая файловая система HDFS
Лекция 2. Основы Hadoop
Лекция 1. Введение в Big Data и MapReduce
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL"
СУБД 2013 Лекция №10 "Нереляционное решение в области баз данных — NoSQL" Час...
СУБД 2013 Лекция №9 "Безопасность баз данных"
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"
СУБД 2013 Лекция №5 "Определение узких мест"
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...

Web осень 2013 лекция 6

  • 1. Работа с базой. Django ORM Александр Бекбулатов
  • 2. Где хранить данные На клиенте • Cookie (до 4Кб) • HTML5 Web Storage (до 5Мб) На сервере • В памяти • На диске • На диске и в памяти 2
  • 3. Работа с базой 1. Представление о СУБД 2. Проектирование баз данных 3. Основные операции SQL 4. Работа с базами данных в python 5. Работа с базами данных в django 3
  • 4. Представление о СУБД База данных взаимосвязанная информация (данные) об объектах, которая организованна специальным образом и хранится на каком-либо носителе. СУБД совокупность программных и лингвистических средств общего или специального назначения, обеспечивающих управление созданием и использованием баз данных. 4
  • 5. Представление о СУБД Функции СУБД  управление данными на дисках и в оперативной памяти  журнализация изменений, резервное копирование и восстановление базы данных после сбоев;  поддержка языков БД (язык определения данных, язык манипулирования данными). 5
  • 6. Реляционная модель данных  Таблица – отношение, relation  Строка – кортеж, tuple  Столбец – атрибут, column Car Key 1 2 3 Model Toyota Camry Audi A4 Honda Civic Color Key 1 2 Color 1 2 2 Name Black Pink Year 2010 2013 2013 6
  • 7. Реляционная модель данных Cousine Key 1 2 Ingredient Key 1 2 3 Name Baked fish Pork Chops Name Pork Lamb Salmon Type Main Course Main Course CousineIngredient CousineKey IngredientKey 1 3 2 1 7
  • 8. Реляционная модель данных Задачи проектирования  Обеспечение хранения в БД всей необходимой информации.  Обеспечение возможности получения данных по всем необходимым запросам.  Сокращение избыточности и дублирования данных.  Обеспечение целостности данных (правильности их содержания): исключение противоречий в содержании данных, исключение их потери и т.д. 8
  • 9. Реляционная модель данных Проектирование на практике  Логическое разделение сущностей  Выделение синтетических первичных ключей  Связи 1:N, N:1 реализуются через внешний ключ  Связи N:M реализуются через промежуточную таблицу  Атрибут с фиксированным числом значений – внешняя таблица либо поле типа enum 9
  • 11. SELECT SELECT * FROM users WHERE age > 10; SELECT * FROM users WHERE name = 'masha'; SELECT max(age) FROM users; SELECT id, name, length(name) AS len FROM users WHERE email LIKE '%@mail.ru' AND age > 10 ORDER BY name DESC LIMIT 10 OFFSET 15 11
  • 12. SELECT. Агрегация Агрегатные функции: COUNT, SUM, AVG, GROUP_CONCAT SELECT name, count(id) cnt FROM users GROUP BY name ORDER BY cnt HAVING cnt > 1 12
  • 13. SELECT. JOIN SELECT h.name, a.name FROM heroes h, abilities a WHERE h.id = a.hero_id SELECT h.name, a.name FROM heroes h INNER JOIN abilities a ON h.id = a.hero_id SELECT h.name, a.name FROM heroes h LEFT JOIN abilities a ON h.id = a.hero_id 13
  • 14. SELECT. Вложенные запросы SELECT title FROM article t1 JOIN ( SELECT rubric_id, MAX(id) max_id FROM article GROUP BY rubric_id LIMIT 5 ) t2 ON t1.id = t2.max_id; 14
  • 15. INSERT, UPDATE, DELETE INSERT INTO users (name, age) VALUES ('Petr', 10); UPDATE users SET age = 20 WHERE name = 'Petr'; UPDATE users SET rating = rating + 1; DELETE FROM users WHERE name = 'Masha'; DELETE FROM users WHERE age > 150; 15
  • 16. Индексы Проектирование на практике  Создавать индексы для полей, по которым происходит JOIN  Создавать индексы для полей, по которым фильтруются записи (WHERE)  Создавать индексы для полей, по которым идет сортировка (ORDER)  Проверять план выполнения запроса (EXPLAIN)  Управление оптимизатором (принудительное использование индекса, порядок соединения таблиц) 16
  • 17. Работа с базами данных в python 17
  • 18. MySQLdb import MySQLdb db = MySQLdb.connect( host="localhost", user="joebob", passwd="moonpie", db="thangs") cursor = db.cursor() 18
  • 19. MySQLdb cursor.execute('update users set age = age + 1 where name = %s', (name,)) cursor.execute('select * from users') users = cursor.fetchall() cursor.execute('select * from users where name = %s', (name,)) user = cursor.fetchone() 19
  • 20. MySQLdb cursor.executemany( "INSERT INTO users (name, age) VALUES (%s, %s)", [ ("Igor", 18 ), ("Petr", 16 ), ("Dasha", 17 ) ]) db.close() 20
  • 21. MySQLdb Зачем плейсхолдеры? email = "' OR '1'='1" cursor.execute("SELECT * FROM users WHERE email = '%s'" % email) Документация http://mysql-python.sourceforge.net/MySQLdb.html 21
  • 22. Работа с базами данных в django 22
  • 23. Классы в Python class Employee(object): def __init__(self, name, salary): self.name = name self.salary = salary def __unicode__(self): return unicode(self.name) def get_info(self): return "Name : %s, Salary: %s" % (self.name, self.salary) class Programmer(Employee): def __init__(self, name, salary, lang): super(Programmer, self).__init__(name, salary) self.lang = lang 23
  • 24. Классы в Python >>> e1 = Programmer(u'Vasya', 100, 'VB') >>> print u'Welcome %s' % e1 Welcome Vasya >>> e1.get_info() u'Name : Vasya, Salary: 100' >>> e1.lang 'VB' 24
  • 25. Raw SQL vs ORM cursor.execute('select * from users where age > 18') for user in cursor.fetchall(): pk, name, age = user print name VS for user in User.objects.filter(age__gt=18): print user.name 25
  • 26. Модели и типы данных class Post(models.Model): title = models.CharField(max_length=255) content = models.TextField() creation_date = models.DateTimeField(default=datetime.datetime.now) def __unicode__(self): return self.title def get_absolute_url(self): return '/post/%d/' % self.pk def get_next_post(self): """Return the next entry""" class Meta: ordering = ['-creation_date’] 26
  • 27. Модели и типы данных Типы данных Mysql varchar(N) longtext tinyint(1) int(11) smallint(5) unsigned date datetime Типы полей Django CharField EmailField SlugField ImageField TextField BooleanField IntegerField PositiveSmallIntegerField DateField DateTimeField 27
  • 28. Модели и типы данных Свойства полей моделей null, blank, choices, db_index, default, editable, help_text, max_length, primary_key, unique, unique_for_date, unique_for_month, unique_for_year, verbose_name https://docs.djangoproject.com/en/dev/ref/models/fields/ 28
  • 29. Связи между таблицами class Post(models.Model): title = models.CharField(max_length=255) content = models.TextField() creation_date = models.DateTimeField(default=datetime.datetime.now) category = models.ForeignKey(Category, on_delete=models.SET_NULL) tags = models.ManyToManyField(Tag) 29
  • 30. Связи между таблицами ForeignKey, OneToOneField ForeignKey = IntegerField + Constraint OneToOneField = ForeignKey + unique post.category – связанный объект (отдельный запрос к связанной сущности) post.category_id – значение атрибута модели (просто id) В обратную сторону: category.post_set.all() 30
  • 31. Связи между таблицами ForeignKey, OneToOneField Изменение/удаление внешнего ключа • • • • RESTRICT -> models.PROTECT CASCADE -> models.CASCADE SET NULL -> models.SET_NULL NO ACTION -> models.DO_NOTHING 31
  • 33. Связи между таблицами ManyToManyField post.tags – related manager post.tags.all() В обратную сторону: tag.post_set.all() 33
  • 34. ORM API python manage.py shell >>> from blog.models import Category, Post >>> from django.db import connection >>> # Вставка и замена >>> >>> >>> 1 >>> >>> c = Category(title="Python") c.save() c.id c.title="About Python" c.save() 34
  • 35. ORM API python manage.py shell >>> print 'n'.join(q['sql'] for q in connection.queries) INSERT INTO `blog_category` (`title`, `description`) VALUES ('Python', '') SELECT (1) AS `a` FROM `blog_category` WHERE `blog_category`.`id` = 1 LIMIT 1 UPDATE `blog_category` SET `title` = 'About Python', `description` = '' WHERE `blog_category`.`id` = 1 35
  • 36. ORM API >>> # Выборка >>> Category.objects.all() [<Category: About Python>] >>> print Category.objects.all().query SELECT `blog_category`.`id`, `blog_category`.`title`, `blog_category`.`description` FROM `blog_category` >>> Category.objects.filter(id=1) [<Category: About Python>] >>> c = Category.objects.get(id=1) >>> c <Category: About Python> >>> c.post_set.all() [] 36
  • 37. ORM API >>> c.post_set.create(title="New post", content="Many words") <Post: New post> >>> c.post_set.count() 1 >>> p = Post.objects.get(title="New post") >>> p.category <Category: About Python> >>> p.category_id 1 >>> Post.objects.filter(category__title="About Python") <Post: New post> >>> c.delete() 37
  • 39. Manager и RelatedManager Методы Manager  slice [10:20]  .all(), .filter(), .exclude(), .order_by()  .values(), .values_list()  .get(), .get_or_create(), .count(), .exists()  .select_related(), .prefetch_related()  .update(), .delete() 39
  • 40. Manager и RelatedManager Методы RelatedManager  .create(**kwargs)  .add(obj1[, obj2, ...])  .remove(obj1[, obj2, ...])  .clear() 40
  • 41. Особенности QuerySet Queryset ленивый qs = Category.objects.all() if not user.is_admin: qs = qs.filter(active=True) print qs.count() 41
  • 42. Особенности QuerySet Избегайте лишних запросов в базу Foreign key кешируется post.category Queryset – нет. Если нужно использовать несколько раз – кешируйте явно question_list = list(Question.objects.all()) 42
  • 43. Особенности QuerySet Атомарное обновление Question.objects.filter(pk=10) .update(rating=models.F('rating') + 1) https://docs.djangoproject.com/en/dev/ref/models/querysets/ 43
  • 44. Создание базы CREATE DATABASE ask_db CHARACTER SET utf8 COLLATE utf8_general_ci; GRANT ALL PRIVILEGES ON ask_db.* TO ask_user@localhost identified BY 'secret'; 44
  • 45. Подключение базы DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'ask_db', 'USER': 'ask_user', 'PASSWORD': 'secret', 'HOST': '', 'PORT': '', } } 45
  • 46. Полезные команды  Проверка моделей python manage.py validate  Вывод SQL python manage.py sqlall <app_name>  Выполнение SQL в базе python manage.py syncdb 46
  • 47. SQL. Создание таблиц CREATE TABLE `blog_post` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `content` longtext NOT NULL, `creation_date` datetime NOT NULL, `category_id` integer NOT NULL ) ; ALTER TABLE `blog_post` ADD CONSTRAINT `category_id_refs_id_e0428883` FOREIGN KEY (`category_id`) REFERENCES `blog_category` (`id`); ALTER TABLE `blog_post_tags` ADD CONSTRAINT `post_id_refs_id_c9e37cca` FOREIGN KEY (`post_id`) REFERENCES `blog_post` (`id`); CREATE INDEX `blog_post_42dc49bc` ON `blog_post` (`category_id`); 47
  • 48. SQL. Удаление и изменение таблиц DROP TABLE blog_post; ALTER TABLE users ADD COLUMN language enum('ru', 'en') NOT NULL DEFAULT 'ru' after name; ALTER TABLE users DROP COLUMN langauge; ALTER TABLE users ADD INDEX ('name'); ALTER TABLE users CHANGE nickname fullname varchar(255) NOT NULL; 48
  • 49. Миграции 1. DROP DATABASE, CREATE DATABASE 2. DROP TABLE, CREATE TABLE 3. ALTER TABLE 4. South 49
  • 50. South • Автоматическое создание миграций • Поддержка различных СУБД • Прямые и обратные миграции 50
  • 51. South Workflow 1. Создать миграцию ./manage.py schemamigration ask --initial 2. Применить миграцию ./manage.py migrate ask 3. Изменить модель 4. Создать миграцию ./manage.py schemamigration ask --auto 5. Применить миграцию ./manage.py migrate ask 51
  • 52. 1. MySQL http://dev.mysql.com/doc/refman/5.5/en/index.html 2. Mysqldb http://mysql-python.sourceforge.net/MySQLdb.html 3. Django http://docs.djangoproject.com/en/dev/ 4. Django Debug Toolbar https://github.com/django-debugtoolbar/django-debug-toolbar 52
  • 53. 1. Установить Django Debug Toolbar 2. Установить MySQL, python-mysqldb. Создать базу данных и пользователя для работы с базой 3. Описать модели для проекта «Вопросы и ответы» 4. Наполнить базу тестовыми данными 53