Изучаем Python. №19. Работа с базой данных SQLIte.


Python отлично работает с базами данных. Кроме того в нем уже есть предустановленная база данных SQLite, что значительно упрощает разработку небольших приложений использующих локальную базу данных для хранения информации.
Сегодня я покажу основы использования SQLite в связке с python.
Для начала нам нужен инструментарий для работы с SQLite базой данных. Установите в своем Firefox дополнение SQLite Manager — это визуальная среда управления таблицами нашей базы. Это нужно, чтобы упростить дальнейшую работу.





Теперь перейдем в папку с нашим проектом (у меня это C:\Python\projects ) и создадим наш рабочий файл main.py
Пробежимся по азам подключения к базам данных. Поскольку SQLite все данные хранит в одном файле, то и доступ к ней не требует логинов и паролей. Мы просто напрямую обращаемся к базе и делаем выборку/вставку. В этом есть свои плюсы и минусы. Но сейчас не об этом. Для подключения достаточно указать всего лишь расположение файла и все.
Делается это так:

import sqlite3
conn = sqlite3.connect('my.db')

Если такой базы нет, то она создается автоматически. Расширение базы можете ставить и такое my.sqlite. Чтобы подключиться к базе через SQLite Manager, нужно просто указать где она лежит.
Сейчас я покажу код создания базы данных и таблиц, но лучше делать это через SQLite Manager.

# -*- coding: utf-8 -*-
import sqlite3
#Подключение к базе
conn = sqlite3.connect('my.sqlite')
#Создание курсора
c = conn.cursor()
#Создание таблицы
c.execute('''CREATE TABLE users (id int auto_increment primary key,name varchar, password varchar)''')
#Наполнение таблицы
c.execute("INSERT INTO users (name,password) VALUES ('admin','123')")
#Подтверждение отправки данных в базу
conn.commit()
#Завершение соединения
c.close()
conn.close()

Если так сделать, то таблица заполниться с дополнительным полем rowid, что нам совсем не нужно:
Изучаем Python. №19. Работа с базой данных SQLIte.
Поэтому предлагаю удалить эту базу и создать новую с именем my.db уже в самом SQLite Manager создать таблицу users.
Изучаем Python. №19. Работа с базой данных SQLIte.

И с помощью вот такой программки регистрации можем заполнить нашу таблицу:

# -*- coding: utf-8 -*-
import sqlite3
conn = sqlite3.connect('my.db')
c = conn.cursor()

#Функция занесения пользователя в базу
def add_user(username,userpass):
    c.execute("INSERT INTO users (name,password) VALUES ('%s','%s')"%(username,userpass))
    conn.commit()

#Вводим данные
name = input("Введите Логин\n")
passwd = input("Введите Пароль\n")
print('\n')

#Делаем запрос в базу
print("Список пользователей:\n")
add_user(name,passwd)
c.execute('SELECT * FROM users')
row = c.fetchone()

#выводим список пользователей в цикле
while row is not None:
   print("id:"+str(row[0])+" Логин: "+row[1]+" | Пароль: "+row[2])
   row = c.fetchone()

# закрываем соединение с базой
c.close()
conn.close()

Результат:

Введите Логин
Виталий
Введите Пароль
123


Список пользователей:

id:1 Логин: Виталий | Пароль: 123

Дополнительный материал:
1. https://docs.python.org/3/library/sqlite3.html
2. http://john16blog.blogspot.ru/2011/03/python-sqlite3.html

Как видите, ничего сложного. В следующем уроке мы соединимся с базой данных MySQL.
Благодарю за внимание. Регистрируйтесь на форуме http://forum.slusar.su/ и подписывайтесь на мои новости.

Или подробней читайте тут:



Введи свой e-mail:

13 thoughts on “Изучаем Python. №19. Работа с базой данных SQLIte.

  1. А почему такие глюки бывают? (с этими «добавочными» полями rowid)
    Попробовал простой вэб-сервис накнопать (для проверки знаний — сразу скажу Пока Маловато знаний, слабовато получается 🙂
    Но пока таких вещей, как заполнение дополнительным полем rowid не встретил.
    Проверял и в консоле, и Sqliteman (такой себе менеджер) — всё как по маслу без лишних полей.

    Описал схему в файде schema.sq):
    drop table if exists users;
    create table users (
    id integer not null primary key autoincrement,
    username text,
    login text not null,
    pswd text not null,
    email text,
    info text
    );
    drop table if exists blogs;
    create table blogs (
    id integer not null primary key autoincrement,
    user_id integer not null,
    title text not null,
    text text not null,
    foreign key(user_id) references users(id)
    );

    и в приложении таблицы создались отлично (куусочек кода):

    #!/usr/bin/env python
    # coding: utf8

    # все импорты
    import sqlite3
    import os
    from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash

    # конфигурация
    DATABASE = ‘mybase.db’
    DEBUG = True
    SECRET_KEY = ‘development_key’
    USERNAME = ‘Wladimir’
    LOGIN = ‘admin’
    PASSWORD = ‘default’
    EMAIL = ‘wladimir@mail.edu’
    INFO = ‘My first information.’

    # приложение
    app = Flask(__name__)
    app.config.from_object(__name__)

    # загружаю конфигурацию и переопределяю часть конфига через переменную окружения
    app.config.update(dict( DATABASE=os.path.join(app.root_path, ‘mybase.db’),\
    DEBUG=True,\
    SECRET_KEY=’development key’,\
    USERNAME=’Wladimir’,\
    LOGIN=’admin’,\
    PASSWORD=’default’,\
    EMAIL=’wladimir@mail.edu’,\
    INFO=’My first information about me.’))

    app.config.from_envvar(‘MYBASE_SETTINGS’, silent=True)

    def connect_db():
    »’Соединяет с указанной базой данных»’
    x = sqlite3.connect(app.config[‘DATABASE’])
    x.row_factory = sqlite3.Row
    return x

    def init_db():
    »’Инициализация по схеме»’
    with app.app_context():
    db = get_db()
    with app.open_resource(‘schema.sql’, mode=’r’) as f:
    db.cursor().executescript(f.read())
    db.commit()

    # ну и тут … всякий «не интересный» код…… 🙂

    if __name__ == ‘__main__’:
    init_db() # инициализация (после каждого запуска создает чистую базу; убрать)
    app.run()
    —————-
    Можно просто импортировать в консоле (модуль мой называется mynet.py, тогда):
    >>> from mynet import init_db
    >>> init_db()
    И так тоже всё создаётся прекрасно, без глюков с доп полями.

    Хотелось бы понимать, почему такие «глюки» бывают?

      1. Спасибо.
        Из уроков по MySql: там мы логинимся к базе root-ом или другим пользователем, у которого должны быть права на эту базу. А как этот механизм реализован в Sqlite? Он вообще присутствует?

        1. Да. Вся база в одном файле. И мы считываем данные с файла посредством sql запросов

  2. Извиняюсь перед админом за тот верхний коммент — ну это только для админа как вопрос, а так всё равно отступы слетели, ничего не понятно (к тому же слишком длинный и уже не читабельный). Так что если удалите — совсем не обижусь 🙂 Но, если можно, по вопросу что-нибудь скажите.
    Спасибо Вам. Хорошие уроки, прогресс уже есть, однозначно!

  3. Возможно кому-то будет интересно о ROWID:
    Почитал об этом rowid. Интересно, что в некоторых источниках я нашёл такую информацию:
    — это директива, выдающая уникальный идентификатор записи
    — называют еще «псевдостобец», котрый отсут­ствует в таблицах в явном виде, но может быть использован в запросах.
    — его нет на самом деле в таблице, он каким-то образом «вычисляется» для внутреннего использования (по большей мере).
    Но при таком нововведении, что сделал в своё время Оракл и за ним поледовали «последователи», происходят некоторое нарушения целостности.
    Что нарушается (и кое-что надо учитывать, если пользователь хочет использовать этот rowid): = цитирую =

    * существование ROWID противоречит как минимум двум из двенадцати известных правил Кодда, описывающих тре­бования к реляционной СУБД. Во-первых, ROWID нарушает правило но­мер 2, которое гласит: «К каждому элементу данных должен быть обес­печен доступ при помощи комбинации имени таблицы, первичного ключа строки и имени столбца». В данном случае ROWID не является первич­ным ключом, хотя ввиду его уникальности для каждой строки он может выступать в роли первичного ключа.

    * нарушается правило Кодда номер 8: «Прикладные програм­мы не должны зависеть от используемых способов хранения данных на носителях и методов обращения к ним». Нарушение этого правила про­исходит из-за того, что ROWID по своей сути является физической ко­ординатой записи, поэтому он будет изменяться в случае пересоздания таблицы, перезагрузки данных, перемещения таблицы из одного таблич­ного пространства в другое и т.п. Однако ROWID уникален и неизменен в течение сеанса пользователя, поэтому приложение может считать его неизменным.

    ROWID существенно упрощает работу с базой данных, поскольку поз­воляет однозначно идентифицировать любую строку таблицы, что, в част­ности, позволяет удалять и редактировать строки таблиц без первичного ключа. Кроме того, поиск строки по ее ROWID является самым быстрым из возможных, что положительно сказывается на быстродействии прило­жений, активно модифицирующих данные. Однако ROWID является спе­цифической особенностью Oracle (ну судя по примерам — уже не только Oracle -моё примечание), а следовательно, его нельзя применять при разработке приложений, рассчитанных на работу с базами других ти­пов (вполне возможно, что реализация rowid в других БД будет несколько различаться (?) — моё примечание)

  4. Здравствуйте, спасибо за статьи, очень познавательно. Не могли бы Вы помочь мне с одной проблемой? Как можно установить часовой пояс для базы? Я создаю отдельные колонки для даты и времени с типом DATETIME и значением по умолчанию CURRENT_TIME и CURRENT_DATE соответственно. Все работает как нужно, за исключением, того, что время на 3 часа меньше, из-за этого даже дата записывается неверно(между 0 и 3 часами ночи). Два дня убил на это, решения в интернете не работают для python или у меня руки кривые)). Если можете помочь в моей проблеме, буду благодарен)

    1. Напоминаю, что у сайта есть форум: http://forum.slusar.su/ , где можно задавать волнующие вас вопросы. Какая у вас ОС? Установлено ли время нормально, посмотрите на часовой пояс, чтобы он соответствовал вашей стране.

      1. Спасибо за ответ, ОС XUBUNTU 16.06 На машине время стоит верное. Я ужу решил проблему, пришлось переписать немалый кусок кода используя пайтоновский datetime, зато все заработало как надо))

  5. А если у меня в базе данных есть столбец, в котором информация должна быть в виде списка, например:
    Характеристики:
    1.
    2.
    И каждый пункт, соответственно, на сайте должен выводиться с новой строки. Как это реализовать?

  6. Я новичок, прошу сильно не пинать. Вот такая ошибка по второму примеру. И если есть у кого-нибудь список толковых ресурсов по SQL скиньте плиз, буду очень благодарен =)

    Введите Логин
    444
    Введите Пароль
    333

    Traceback (most recent call last):
    Список пользователей:

    File «C:/test py/testSQL.py», line 15, in
    add_user(name,passwd)
    File «C:/test py/testSQL.py», line 7, in add_user
    c.execute(«INSERT INTO users (name,password) VALUES (‘%s’,’%s’)»%(username,userpass))
    sqlite3.OperationalError: no such table: users

    Process finished with exit code 1

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

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