Архив рубрики: База знаний

Python SQLite — учебное пособие на русском языке

Учебное пособие по программированию на Python для базы данных SQLite.

Оглавление

SQLite

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

Установка SQLite

sudo apt install sqlite3

Запускаем модуль sqlite3 и консоль пригласит для работы с базой данных:
sqlite>
Список команд для работы с базой данных sqlite> .help

Создание базы данных SQLite

Вся база данных SQLite хранится в обычном файле. Используем команду .open dbname.db. Если база не существует — она будет создана, если существует — будет открыта.

sqlite> .open ydb.db

Python SQLite — как подключаться к базе и отправлять запросы

Для примера получим версию базы данных SQLite.

В первом скрипте рассмотрим работу с базой данных классическим способом: откроем базу – выполним запрос – закроем базу и освободим ресурсы.

#!/usr/bin/python

import sqlite3
import sys

con = None

try:
    con = sqlite3.connect('ydb.db')

    cur = con.cursor()
    cur.execute('SELECT SQLITE_VERSION()')

    data = cur.fetchone()[0]

    print(f"SQLite version: {data}")

except sqlite3.Error as e:

    print(f"Error {e.args[0]}")
    sys.exit(1)

finally:

    if con:
        con.close()
SQLite version: 3.31.1

Рассмотрим код подробнее:

import sqlite3

Импортируем библиотеку sqlite3.

con = None

Объявляем переменную con значением None. Если мы не сможем соединиться с базой данных (например, диск переполнен), а у нас не была бы определена переменная соединения — это приведёт к ошибке в блоке finally.

con = sqlite3.connect('ydb.db')

Подключаемся к базе данных ydb.db. Метод connect возвращает объект соединения.

cur = con.cursor()
cur.execute('SELECT SQLITE_VERSION()')

Из соединения мы получаем объект курсора. Курсор используется для обхода записей из полученных результатов. Мы вызываем метод курсора execute и выполняем SQL-запрос.

data = cur.fetchone()[0]

Поскольку мы получаем только одну запись, мы вызываем метод fetchone.

print(f"SQLite version: {data}")

Полученные данные выводим в консоль.

except sqlite3.Error as e:

    print(f"Error {e.args[0]}")
    sys.exit(1)

В случае ошибки получаем исключение — выводим сообщение об ошибке и выходим из скрипта с кодом ошибки 1.

finally:

    if con:
        con.close()

con.close() закрывает работу с базой данных и освобождаем ресурсы.

Во втором примере мы снова получаем версию базы данных SQLite. На этот раз мы используем контекстный менеджер with.

#!/usr/bin/python

import sqlite3

with sqlite3.connect('ydb.db') as con:

    cur = con.cursor()
    cur.execute('SELECT SQLITE_VERSION()')

    data = cur.fetchone()[0]

    print(f"SQLite version: {data}")

Код выглядит компактнее, читается проще.

Python SQLite — метод execute

Создадим таблицу cars и вставим в нее несколько строк. Для добавления данных используем команду execute.

import sqlite3


with sqlite3.connect('ydb.db') as con:

    cur = con.cursor()

    cur.execute("DROP TABLE IF EXISTS cars;")
    cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
    cur.execute("INSERT INTO cars VALUES(1,'Audi',52642)")
    cur.execute("INSERT INTO cars VALUES(2,'Mercedes',57127)")
    cur.execute("INSERT INTO cars VALUES(3,'Skoda',9000)")
    cur.execute("INSERT INTO cars VALUES(4,'Volvo',29000)")
    cur.execute("INSERT INTO cars VALUES(5,'Bentley',350000)")
    cur.execute("INSERT INTO cars VALUES(6,'Citroen',21000)")
    cur.execute("INSERT INTO cars VALUES(7,'Hummer',41400)")
    cur.execute("INSERT INTO cars VALUES(8,'Volkswagen',21600)")

Рассмотрим подробнее:

cur.execute("DROP TABLE IF EXISTS cars;")

Удаляем таблицу, если она уже существует.

cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")

Создаём новую таблицу cars с тремя столбцами: id, name, price.

cur.execute("INSERT INTO cars VALUES(1,'Audi',52642)")
cur.execute("INSERT INTO cars VALUES(2,'Mercedes',57127)")

Эти две строки вставляют в таблицу два автомобиля. Благодаря использованию контекстного менеджера with изменения фиксируются автоматически. В противном случае нам пришлось бы фиксировать их вручную.

sqlite> .mode column
sqlite> .headers on

Выведем записанные данные в консоль с помощью модуля sqlite3. Изменим способ отображения данных в консоли — используем режим столбцов и отобразим заголовки.

sqlite> select * from cars;
id          name        price
----------  ----------  ----------
1           Audi        52642
2           Mercedes    57127
3           Skoda       9000
4           Volvo       29000
5           Bentley     350000
6           Citroen     21000
7           Hummer      41400
8           Volkswagen  21600

Python SQLite — метод executemany

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

Python SQLite — executemany INSERT

import sqlite3


cars = (
    (1, 'Audi', 52642),
    (2, 'Mercedes', 57127),
    (3, 'Skoda', 9000),
    (4, 'Volvo', 29000),
    (5, 'Bentley', 350000),
    (6, 'Hummer', 41400),
    (7, 'Volkswagen', 21600)
)

with sqlite3.connect('ydb.db') as con:

    cur = con.cursor()

    cur.execute("DROP TABLE IF EXISTS cars")
    cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
    cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)

Вставляем сразу восемь строк в таблицу.

cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)

Первый параметр — запрос SQL, второй параметр — кортеж кортежей.

Python SQLite — executemany SELECT

Метод executemany используется только для вставки данных. Иногда ошибочно пытаются получить данные по фильтру из списка значений с помощью executemany. Но для этого используется метод execute с подстановкой значений.

cur.execute('SELECT * FROM cars WHERE name in ({0})'.format(', '.join('?' for _ in names)), names)

Python SQLite — метод executescript

Рассмотрим способ создания таблицы автомобилей с помощью executescript. Будем фиксировать изменения вручную и добавим собственную обработку ошибок.

import sqlite3
import sys

con = None

try:
    con = sqlite3.connect('ydb.db')

    cur = con.cursor()

    cur.executescript("""
        DROP TABLE IF EXISTS cars;
        CREATE TABLE cars(id INT, name TEXT, price INT);
        INSERT INTO cars VALUES(1,'Audi',52642);
        INSERT INTO cars VALUES(2,'Mercedes',57127);
        INSERT INTO cars VALUES(3,'Skoda',9000);
        INSERT INTO cars VALUES(4,'Volvo',29000);
        INSERT INTO cars VALUES(5,'Bentley',350000);
        INSERT INTO cars VALUES(6,'Citroen',21000);
        INSERT INTO cars VALUES(7,'Hummer',41400);
        INSERT INTO cars VALUES(8,'Volkswagen',21600);
        """)

    con.commit()

except sqlite3.Error as e:

    if con:
        con.rollback()

    print(f"Error {e.args[0]}")
    sys.exit(1)

finally:

    if con:
        con.close()

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

con.commit()

Без контекстного менеджера with изменения должны быть зафиксированы с помощью метода commit.

except sqlite.Error as e:

    if con:
        con.rollback()

    print(f"Error {e.args[0]}")
    sys.exit(1)

В случае ошибки изменения откатываются con.rollback(), а на терминал выводится сообщение об ошибке.

Python SQLite — метод lastrowid

Иногда требуется получить id последней строки таблицы в базе данных. В Python SQLite используем атрибут lastrowid объекта курсора.

import sqlite3

with sqlite3.connect(':memory:') as con:

    cur = con.cursor()
    cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT);")
    cur.execute("INSERT INTO friends(name) VALUES ('Tom');")
    cur.execute("INSERT INTO friends(name) VALUES ('Rebecca');")
    cur.execute("INSERT INTO friends(name) VALUES ('Jim');")
    cur.execute("INSERT INTO friends(name) VALUES ('Robert');")

    last_row_id = cur.lastrowid

    print(f"The last Id of the inserted row is {last_row_id}")

:memory: — база данных, которая создаётся временно.

Python SQLite — получение данных с помощью fetchall

Метод fetchall извлекает все (или все оставшиеся) строки из набора результатов запроса и возвращает список кортежей.

import sqlite3


with sqlite3.connect('ydb.db') as con:

    cur = con.cursor()
    cur.execute("SELECT * FROM cars")

    rows = cur.fetchall()

    for row in rows:
        print(f"{row[0]} {row[1]} {row[2]}")

Python SQLite — метод fetchone

Метод fetchone возвращает следующую строку полученных результатов. Возвращает один кортеж или None, когда больше нет доступных данных.

import sqlite3

con = sqlite3.connect('ydb.db')

with con:

    cur = con.cursor()
    cur.execute("SELECT * FROM cars")

    while True:

        row = cur.fetchone()

        if row == None:
            break

        print(f"{row[0]} {row[1]} {row[2]}")

Python SQLite — row_factory

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

import sqlite3

con = sqlite3.connect('ydb.db')

with con:

    con.row_factory = sqlite3.Row

    cur = con.cursor()
    cur.execute("SELECT * FROM cars")

    rows = cur.fetchall()

    for row in rows:
        print(f"{row['id']} {row['name']} {row['price']}")

Python SQLite — как проверить, существует ли база данных

Невозможно проверить, существует ли файл базы данных с помощью метода connect. Метод просто подключается к базе данных, если файл существует. Если файл не существует, файл базы данных создается. Существование файла базы данных можно проверить с помощью стандартной функции os.path.exist.

import os
import sqlite3


if not os.path.exists('ydb.db'):

    con = sqlite3.connect('ydb.db')

    with con:

        cur = con.cursor()
        cur.execute("DROP TABLE IF EXISTS cars")
        cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
        cur.execute("INSERT INTO cars VALUES(1,'Audi', 52642)")
        cur.execute("INSERT INTO cars VALUES(2,'Mercedes', 57127)")
        cur.execute("INSERT INTO cars VALUES(3,'Skoda',9000)")
        cur.execute("INSERT INTO cars VALUES(4,'Volvo',29000)")
        cur.execute("INSERT INTO cars VALUES(5,'Bentley', 350000)")
        cur.execute("INSERT INTO cars VALUES(6,'Citroen',21000)")
        cur.execute("INSERT INTO cars VALUES(7,'Hummer',41400)")
        cur.execute("INSERT INTO cars VALUES(8,'Volkswagen', 21600)")

else:

    with sqlite3.connect('ydb.db') as con:

        cur = con.cursor()
        cur.execute("SELECT * FROM cars")
        rows = cur.fetchmany(2)

        print(rows)

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

if not os.path.exists('test.db'):

  con = sqlite3.connect('test.db')
  ...

Python SQLite — подстановка значений в SQL-запрос

Когда мы подставляем значения в запросы, мы используем заполнители вместо того, чтобы напрямую записывать значения. Такие запросы называются параметризованными. Параметризованные запросы повышают безопасность и производительность.

Модуль Python sqlite3 поддерживает два типа заполнителей: вопросительные знаки и именованные параметры.

Подстановка значений с помощью вопросительных знаков

import sqlite3

uId = 1
uPrice = 62300

con = sqlite3.connect('ydb.db')

with con:

    cur = con.cursor()
    cur.execute("UPDATE cars SET price=? WHERE id=?", (uPrice, uId))

    print(f"Number of rows updated: {cur.rowcount}")

Метод rowcount возвращает количество обновленных строк.

Подстановка значений с помощью именованных параметров

import sqlite3

uId = 4

con = sqlite3.connect('ydb.db')

with con:

    cur = con.cursor()
    cur.execute("SELECT name, price FROM cars WHERE Id=:Id", {"Id": uId})

    row = cur.fetchone()
    print(f"{row[0]}, {row[1]}")

Python SQLite — хранение изображений в базе данных

Вставка изображений

Рассмотрим хранение изображений в базе данных SQLite. Конечно, сохранять изображения в базе данных нецелесообразно.  Общая практика состоит в том, чтобы хранить изображения в каталогах файловой системы и хранить ссылки на изображения в базе данных. Но мы рассмотрим этот приём для общего понимания возможностей SQLite.

sqlite> CREATE TABLE images(id INTEGER PRIMARY KEY, data BLOB);

Для этого примера создаем новую таблицу под названием images. Для изображений используем тип данных BLOB (англ. Binary Large Object — двоичный большой объект) — массив двоичных данных.

import sqlite3
import sys

def readImage():

    fin = None

    try:
        fin = open("sid.jpg", "rb")
        img = fin.read()
        return img

    except IOError as e:

        print(e)
        sys.exit(1)

    finally:

        if fin:
            fin.close()

con = None

try:
    con = sqlite3.connect('ydb.db')

    cur = con.cursor()

    data = readImage()
    binary = sqlite3.Binary(data)
    cur.execute("INSERT INTO images(data) VALUES (?)", (binary,) )

    con.commit()

except sqlite3.Error as e:

    if con:
        con.rollback()

    print(e)
    sys.exit(1)

finally:

    if con:
        con.close()

Рассмотрим скрипт подробнее:

Открываем и считываем изображения из каталога в базе данных.

try:
    fin = open("sid.jpg", "rb")
    img = fin.read()
    return img

Мы считываем двоичные данные из файловой системы. У нас есть изображение в формате JPG, называемое sid.jpg.

binary = sqlite3.Binary(data)

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

cur.execute("INSERT INTO images(data) VALUES (?)", (binary,) )

Получение изображений

Выполним обратную операцию: получим изображение из таблицы базы данных.

import sqlite3
import sys


def writeImage(data):

    fout = None

    try:
        fout = open('sid2.jpg','wb')
        fout.write(data)

    except IOError as e:

        print(e)
        sys.exit(1)

    finally:

        if fout:
            fout.close()

con = None

try:
    con = sqlite3.connect('ydb.db')

    cur = con.cursor()
    cur.execute("SELECT data FROM images LIMIT 1")
    data = cur.fetchone()[0]

    writeImage(data)


except sqlite3.Error as e:

    print(e)
    sys.exit(1)

finally:

    if con:
        con.close()

Python SQLite — метаданные таблиц

Метаданные – это информация о данных в базе данных. Метаданные в SQLite содержат информацию о таблицах и столбцах, в которых мы храним данные.

Метаданные в SQLite можно получить с помощью команды PRAGMA. Объекты SQLite могут иметь атрибуты, которые являются метаданными. Наконец, мы также можем получить конкретные метатеги, запросив таблицу sqlite_master системы SQLite.

import sqlite3

con = sqlite3.connect('ydb.db')

with con:

    cur = con.cursor()

    cur.execute('PRAGMA table_info(cars)')

    data = cur.fetchall()

    for d in data:
        print(f"{d[0]} {d[1]} {d[2]}")

В этом примере мы выполняем команду PRAGMA table_info(имя_таблицы), чтобы получить некоторую информацию о метаданных нашей таблицы cars.

ur.execute('PRAGMA table_info(cars)')

Команда PRAGMA table_info(имя_таблицы) возвращает по одной строке для каждого столбца в таблице cars. Столбцы в результирующем наборе включают порядковый номер столбца, имя столбца, тип данных, может ли столбец быть нулевым или нет, и значение по умолчанию для столбца.

for d in data:
    print(f"{d[0]} {d[1]} {d[2]}")

В следующем примере выведем все строки из таблицы cars с именами их столбцов.

import sqlite3

con = sqlite3.connect('ydb.db')

with con:

    cur = con.cursor()
    cur.execute('SELECT * FROM cars')

    col_names = [cn[0] for cn in cur.description]

    rows = cur.fetchall()

    print(f"{col_names[0]:3} {col_names[1]:10} {col_names[2]:7}")

    for row in rows:
        print(f"{row[0]:<3} {row[1]:<10} {row[2]:7}")

Мы выводим содержимое таблицы cars на консоль. Теперь мы также включаем названия столбцов. Записи выровнены по именам столбцов.

col_names = [cn[0] for cn in cur.description]

Получаем имена столбцов из свойства description объекта cursor.

print(f"{col_names[0]:3} {col_names[1]:10} {col_names[2]:7}")

В этой строке выводятся названия трех столбцов таблицы cars.

for row in rows:
    print(f"{row[0]:<3} {row[1]:<10} {row[2]:7}")

Печатаем строки с помощью цикла for. Данные выровнены по именам столбцов.

id  name       price
1   Audi         62300
2   Mercedes     57127
3   Skoda         9000
4   Volvo        29000
5   Bentley     350000
6   Hummer       41400
7   Volkswagen   21600

В последнем примере перечислим все таблицы в базе данных ydb.db.

import sqlite3

con = sqlite3.connect('ydb.db')

with con:

    cur = con.cursor()
    cur.execute("SELECT name FROM sqlite_master WHERE type='table'")

    rows = cur.fetchall()

    for row in rows:
        print(row[0])

Пример кода выводит на терминал все доступные таблицы в текущей базе данных.

cur.execute("SELECT name FROM sqlite_master WHERE type='table'")

Имена таблиц хранятся внутри системной таблицы sqlite_master.

cars
images

Python SQLite — экспорт данных

Создадим резервную копию таблиц нашей базы данных.

import sqlite3

cars = (
    (1, 'Audi', 52643),
    (2, 'Mercedes', 57642),
    (3, 'Skoda', 9000),
    (4, 'Volvo', 29000),
    (5, 'Bentley', 350000),
    (6, 'Hummer', 41400),
    (7, 'Volkswagen', 21600)
)

def writeData(data):

    f = open('cars.sql', 'w')

    with f:
        f.write(data)


con = sqlite3.connect(':memory:')

with con:

    cur = con.cursor()

    cur.execute("DROP TABLE IF EXISTS cars")
    cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
    cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)
    cur.execute("DELETE FROM cars WHERE price < 30000")

    data = 'n'.join(con.iterdump())

    writeData(data)

В этом примере воссоздаем таблицу cars в временной базе данных. Удаляем некоторые строки из таблицы и сохраняем текущее состояние таблицы в файл cars.sql. Этот файл будет служить резервной копией текущей таблицы.

def writeData(data):

    f = open('cars.sql', 'w')

    with f:
        f.write(data)

Данные из таблицы записываются в файл.

con = sqlite3.connect(':memory:')

Создаем таблицу во временной базе данных.

cur.execute("DROP TABLE IF EXISTS cars")
cur.execute("CREATE TABLE cars(id INT, name TEXT, price INT)")
cur.executemany("INSERT INTO cars VALUES(?, ?, ?)", cars)
cur.execute("DELETE FROM cars WHERE price < 30000")

Создаём таблицу cars, вставляем значения и удаляем строки, где цена меньше 30000.

data = 'n'.join(con.iterdump())

con.iterdump возвращает итератор для дампа базы данных в текстовом формате SQL. Встроенная функция join принимает итератор и объединяет все строки в итераторе, разделенные новой строкой. Эти данные записываются в файл cars.sql с помощью функции writeData.

Python SQLite — импорт данных

Выполним обратную операцию. Импортируем ранее сохранённую таблицу.

import sqlite3


def readData():

    f = open('cars.sql', 'r')

    with f:

        data = f.read()

        return data


con = sqlite3.connect(':memory:')

with con:

    cur = con.cursor()

    sql = readData()
    cur.executescript(sql)

    cur.execute("SELECT * FROM cars")

    rows = cur.fetchall()

    for row in rows:
        print(row)

Python SQLite — транзакции

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

Транзакции начинаются с инструкции BEGIN TRANSACTION и завершаются инструкциями COMMIT или ROLLBACK.

SQLite поддерживает три уровня транзакций: DEFERREDIMMEDIATE and EXCLUSIVE.

  1. DEFERRED – данный режим блокировки является режимом по умолчанию в SQLite. В режиме DEFERRED SQLite начинает блокировать таблицы только после того, как будет начато выполнение какой-либо команды, при этом другие транзакции могут читать данные из таблицы, но не могут их изменять.
  2. IMMEDIATE – в данном режим происходит блокировка базы данных, как только будет выполнена команда BEGIN. При это режим IMMEDIATE в SQLIte допускает, что другие транзакции могут читать данные из базы данных, но не записывать.
  3. EXCLUSIVE – самый высокий уровень блокировки базы данных в SQLite. Режим EXCLUSIVE блокирует базу данных при выполнении команды BEGIN и при этом другие транзакции не могут ни читать данные из базы данных, ни уж тем более изменять данные.

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

import sqlite3
import sys

con = None

try:
    con = sqlite3.connect('ydb.db')
    
    cur = con.cursor()
    cur.execute("DROP TABLE IF EXISTS friends")
    cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)")
    cur.execute("INSERT INTO friends(name) VALUES ('Tom')")
    cur.execute("INSERT INTO friends(name) VALUES ('Rebecca')")
    cur.execute("INSERT INTO friends(name) VALUES ('Jim')")
    cur.execute("INSERT INTO friends(name) VALUES ('Robert')")

    #con.commit()

except sqlite3.Error as e:

    if con:
        con.rollback()

    print(e)
    sys.exit(1)

finally:

    if con:
        con.close()

Мы создаем таблицу friends и пытаемся заполнить ее данными. Однако, как мы увидим, данные не фиксируются.

#con.commit()

Метод фиксации con.commit() закомментирован. Если мы раскомментируем строку, данные будут записаны в таблицу.

Python SQLite autocommit

В режиме автоматической фиксации инструкция SQL выполняется немедленно.

import sqlite3
import sys

con = None

try:
    con = sqlite3.connect('ydb.db', isolation_level = None)
    
    cur = con.cursor()

    cur.execute("DROP TABLE IF EXISTS friends")
    cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)")
    cur.execute("INSERT INTO friends(name) VALUES ('Tom')")
    cur.execute("INSERT INTO friends(name) VALUES ('Rebecca')")
    cur.execute("INSERT INTO friends(name) VALUES ('Jim')")
    cur.execute("INSERT INTO friends(name) VALUES ('Robert')")

except sqlite3.Error as e:

    print(e)
    sys.exit(1)

finally:

    if con:
        con.close()

В этом примере мы подключаемся к базе данных в режиме автоматической фиксации.

con = sqlite3.connect('ydb.db', isolation_level = None)

Смотрите также: Руководство по стилю SQL

Сообщение Python SQLite — учебное пособие на русском языке появились сначала на Веб-студия Юсота.


Source: usota.ru python

CSS — медиа-запросы для различных устройств (@media)

Минимальный набор медиа-запросов для любого сайта на WordPress:

/* Desktop */ 
@media (min-width: 768px) {}

/* Desktop & Tablet */ 
@media (min-width: 481px) {}

/* Tablet landscape */ 
@media (min-width: 768px) and (max-width: 1024px) and (orientation: landscape) {}

/* Tablet*/ 
@media (min-width: 481px) and (max-width: 767px) {}

/* Tablet & Mobile */ 
@media (max-width: 767px) {}

/* Mobile */ 
@media (max-width: 480px) {}

Полный гайд от Francesco Baldan

Сообщение CSS — медиа-запросы для различных устройств (@media) появились сначала на Веб-студия Юсота.


Source: usota.ru knowledge-base

Преобразуем проект на Python в исполняемый файл .EXE с помощью PyInstaller

Внимание! Исполняемый файл будет работать только на той же платформе, на которой он был создан. Например, исполняемый файл, созданный в Windows 10-64 bit, не будет работать в Windows 10-32 bit или в Windows Server. Очевидно, что он также не будет работать на Mac OS или ОС на базе Linux.

Разработчик https://pyinstaller.org/en/stable/

Устанавливаем библиотеку PyInstaller в наше окружение. Важно установить именно в окружение, иначе могут быть проблемы с установкой модулей. Можем получить ошибку “pyinstaller no module named”.

Windows:

py -m pip install pyinstaller

Unix/macOS:

python3 -m pip install pyinstaller

Преобразуем скрипт в программу

pyinstaller myscript.py --onefile --windowed

–onefile – приложение в одном файле
–windowed – не показывать консоль
–console – показывать консоль

У вас появятся две новые папки:
– build
– dist

В папке dist будет лежать наш исполняемый файл.

Ошибки

pyinstaller no module named

  1. Удаляем пакет в папке build и формируем файл заново
  2. Или пробуем добавить установку модуля принудительно с помощью --hidden-import:
pyinstaller myscript.py --onefile --windowed --hidden-import=namemodule

Ошибка «ModuleNotFoundError: No module named ‘setuptools’»

Некоторые пакеты Python используют для развёртывания distutils, но в настоящее время большинство использует setuptools.

Setuptools — это расширение для python-distutils для больших и сложных развёртываний.

Если у вас Ubuntu, Linux Mint, Debian или производный от них дистрибутив, то вы можете установить этот пакет из стандартных репозиториев:

sudo apt install python3-setuptools

Если вы уже установили PIP (а именно пакет python3-pip), то вместо указанной выше команды, можно выполнить такую:

sudo pip3 install --upgrade setuptools

Если у вас Windows:

python -m pip install -U pip setuptools

Сообщение Преобразуем проект на Python в исполняемый файл .EXE с помощью PyInstaller появились сначала на Веб-студия Юсота.


Source: usota.ru python

Yoast SEO — импорт значений

Настройки Yoast хранятся в произвольных полях каждой записи.
Поэтому при импорте значений Yoast SEO — указываем произвольные поля Custom Field.

Значения Yoast SEO записей, товаров WooCommerce

NameCustom FieldValues
Focus Keyword_yoast_wpseo_focuskwText string
SEO Title_yoast_wpseo_titleText string
Meta Description_yoast_wpseo_metadescText string
Meta Robots Index_yoast_wpseo_meta-robots-noindexBlank for default, 1 for noindex, or 2 for index
Meta Robots Follow_yoast_wpseo_meta-robots-nofollowBlank for follow, 1 for nofollow
Meta Robots Advanced_yoast_wpseo_meta-robots-advBlank for default, none, noodp, noydir, noimageindex, noarchive, or nosnippet
Include in Sitemap_yoast_wpseo_sitemap-includeBlank for auto, always, or never
Sitemap Priority_yoast_wpseo_sitemap-prioBlank for auto, 1 to .1
Canonical URL_yoast_wpseo_canonicalCanonical URL of post
301 Redirect_yoast_wpseo_redirectURL to redirect post to
Facebook Title_yoast_wpseo_opengraph-titleText string
Facebook Description_yoast_wpseo_opengraphText string
Facebook Image_yoast_wpseo_opengraph-imageURL to image
Twitter Title_yoast_wpseo_twitter-titleText string
Twitter Description_yoast_wpseo_twitter-descriptionText string

Значения Yoast SEO таксономий: рубрики, категории WooCommerce

NameCustom FieldValues
Focus Keywordwpseo_focuskwText string
SEO Titlewpseo_titleText string
Meta Descriptionwpseo_descText string
Meta Robots Indexwpseo_noindexBlank for default, 1 for noindex, or 2 for index
Include in Sitemapwpseo_sitemap_includeBlank for auto, always, or never
Canonical URLwpseo_canonicalCanonical URL of post
Facebook Titlewpseo_opengraph-titleText string
Facebook Descriptionwpseo_opengraph-descriptionText string
Facebook Imagewpseo_opengraph-imageURL to image
Twitter Titlewpseo_twitter-titleText string
Twitter Descriptionwpseo_twitter-descriptionText string
Twitter Imagewpseo_twitter-imageURL to image

Сообщение Yoast SEO — импорт значений появились сначала на Веб-студия Юсота.


Source: usota.ru seo

Yoast SEO — список переменных

Как создать свою переменную

Допустим мы хотим создать свою переменную writer, которая находится в атрибуте товара. Конечно, можно использовать переменную %%ct_pa_<product-attribute-slug>%%, но для примера рассмотрим принцип создание своей переменной.

add_action('wpseo_register_extra_replacements', 'register_custom_yoast_variables');
function get_writer() {
    global $product;
	$writer = $product->get_attribute( 'pa_writer' );
    return $writer;
}
function register_custom_yoast_variables() {
    wpseo_register_var_replacement('%%writer%%', 'get_writer', 'advanced', 'Значение атрибута товара "Автор"');
}

Основные переменные

НазваниеПеременная ENGПеременная RUSОписание
Дата%%date%%ДатаДату публикации, например «20.02.2020».
Название%%title%%НазваниеTitle — название страницы.
Название родительской страницы%%parent_title%%Заголовок родителяНазвание родительской страницы. Если у текущей страницы нет родительской, выведет текст «(нет родительской)».
Название архива%%archive_title%%Название архива, например: «Рубрика: Новости» или «Категория: Товары для дачи».
Название сайта%%sitename%%Название сайтаНазвание сайта.
Краткое описание сайта%%sitedesc%%ПодзаголовокКраткое описание сайта.
Отрывок%%excerpt%%ОтрывокВыводит отрывок из записи, если есть. Есть нет — выводит отрывок, который генерируется автоматически.
Только отрывок%%excerpt_only%%Только отрывокВыводит отрывок из записи, если есть. Если нет — ничего не выводит.
Метка%%tag%%Выводится только в категории товаров. Выводит название метки, которая есть у товаров в этой категории.
Рубрика%%category%%РубрикаВыводит название рубрики. Несколько рубрик выводит через запятую.
Основная рубрика%%primary_category%%Основная рубрикаОсновная рубрика.
Описание рубрики%%category_description%%Описание рубрикиВыводит описание рубрики или категории.
Описание метки%%tag_description%%Описание меткиОписание метки
Название таксономии%%term_title%%Название таксономии
Описание таксономии%%term_description%%Описание элементаОписание таксономии
Поисковая фраза%%searchphrase%%Выводит поисковую фразу на странице поиска
Разделитель%%sep%%РазделительРазделитель, определенный в теге wp_title() вашей темы. Как правило это дефис «-»

Расширенные переменные

Следующий пример переменных требует лучшего понимания SEO. Если вы не знаете, как использовать эти расширенные переменные, мы рекомендуем вам не использовать их.

ЭтикеткаПеременнаяОписание
Тип столба (сингулярный)%%pt_single%%Заменено на одну метку типа контента
Тип столба (множественное число)%%pt_plural%%Заменено на метку типа контента множественного числа
Модифицированный%%modified%%Заменено на сообщение / страницу измененное время
ID%%id%%Заменено на сообщение/идентификатор страницы
Имя%%name%%Заменено на сообщение / страницу автора ‘ nicename’
Описание пользователя%%user_description%%Заменено на сообщение / страницу ” биографические данные автора’
Номер страницы%%page%%Заменяется текущим номером страницы с контекстом (т. е. Страница 2 из 4)
Pagetotal%%pagetotal%%Заменено на текущую страницу итого
Pagenumber%%pagenumber%%Заменяется на текущий номер страницы
Подпись%%caption%%Заголовок приложения
Ключевое слово Focus%%focuskw%%Заменена ключевая фраза фокусировки сообщений
Term404%%term404%%Заменен на пули, которые вызвали 404
<custom-field-name> (настраиваемое поле)%%cf_<custom-field-name>%%Заменено значением настраиваемого поля posts. Удалите < >
<custom-tax-name> (пользовательская таксономия)%%ct_<custom-tax-name>%%Заменено на посты custom taxonomies, разделенные запятой. Удалите < >
< custom-tax-name> описание (пользовательская таксономия)%%ct_desc_<custom-tax-name>%%Заменено пользовательским описанием таксономий. Удалите < >

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

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

Настраиваемых поля

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

Пользовательские имена полей можно найти с помощью следующих действий. Если у вас есть имя настраиваемого поля, вы его замените &lt;custom-field-name&gt;. Если бы мое пользовательское поле было вызвано myfield, пользовательская переменная была бы %%cf_myfield%%. Если пользовательское поле начинается с подчеркивания, например_anotherfield, пользовательская переменная должна включать подчеркивание следующим образом:%%cf__anotherfield%%.

Пользовательские таксономии

Пользовательские имена таксономий можно найти в адресной строке браузера при просмотре или редактировании элемента.

Пример: edit-tags.php?taxonomy=mycategory&post_type=myposttype

В приведенном выше примере мы редактируем пользовательскую таксономию, называемую mycategory, под пользовательским типом записи myposttype . Если бы я хотел вывести список категорий, назначенных странице myposttype, я бы использовал %%ct_mycategory%%. Если бы я хотел вывести описание отдельной mycategory на странице архива категорий, я бы использовал %%ct_desc_mycategory%%.

Переменные WooCommerce

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

%%ct_product_cat%%Категории товара (через запятую)
%%ct_product_tag%%Метки товара (через запятую)
%%ct_pa_<product-attribute-slug>%%Атрибуты товара (через запятую). Удалите <>, так как они не нужны. Прим.: возможно, что в предварительном просмотре вы не увидите изменений. Но переменная работает, это можно увидеть в исходном коде страницы.

Yoast WooCommerce SEO переменные

Если у вас есть плагин Yoast WooCommerce SEO, эти дополнительные переменные доступны. Плагин платный 😉

%%wc_shortdesc%%Краткое описание (Доступно по состоянию на Yoast WooCommerce SEO 6.2)
%%wc_sku%%Артикул товара. (Доступно по состоянию на Yoast WooCommerce SEO 6.2)
%%wc_brand%%Название бренда. Работает с плагинами “WooCommerce Brands” и “Perfect WooCommerce Brands“. (Доступно по состоянию на Yoast WooCommerce SEO 6.2)
%%wc_price%%Цена товара. (Доступно по состоянию на Yoast WooCommerce SEO 6.2)

Устаревшие переменные

Начиная с версии v7. 7 — Yoast убрали эти переменные, поскольку не видят в них смысла и рекомендуют их не использовать. Но они работают (проверял 1 июня 2020 г.).

%%userid%%Идентификатор автора поста / страницы
%%currenttime%%Текущее время
%%currentdate%%Текущая дата
%%currentday%%Текущий день
%%currentmonth%%Текущий месяц
%%currentyear%%Текущий год

Переменные по умолчанию

Если вы хотите сбросить переменные шаблона заголовка SEO обратно к значениям по умолчанию, используйте следующее переменные. Для дескрипшена значение по умолчанию является пустым. Значения по умолчанию задаются в разделе «Отображение в поисковой выдаче».

%%title%% %%page%% %%sep%% %%sitename%%%Записи, страницы, товары и пользовательские типы записей
%%pt_plural%% Archive %%page%% %%sep%% %%sitename%%Записи, товары и другие пользовательские страницы архивов
%%term_title%% Archives %%page%% %%sep%% %%sitename%%Таксономии
Вы искали %%searchphrase%% %%page%% %%sep%% %%sitename%%Страница результатов поиска
Страница не найдена %%sep%% %%sitename%%404 страница
%%name%%, автор %%sitename%% %%page%%Архивы авторов
%%date%% %%page%% %%sep%% %%sitename%%Архивы дат
The post %%POSTLINK%% appeared first on %%BLOGLINK%%.RSS-канал
%%sitename%% %%page%% %%sep%% %%sitedesc%%Шаблон главной

Сообщение Yoast SEO — список переменных появились сначала на Веб-студия Юсота.


Source: usota.ru seo

Как настроить Yoast SEO для интернет-магазина

Для автоматического заполнения метатегов Title и Description используются SEO-шаблоны. Шаблоны прописываются в настройках Yoast SEO.

 

Рассмотрим, как настроить SEO-шаблоны:

Настройка Title и Description для карточки товара

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

 

Поэтому сниппет должен содержать:
– название товара
– коммерческое слово «купить», «цена» или «заказать»
– цену, если есть возможность указывать цену
– условия оплаты: рассрочка, кредит
– условия доставки: доставка, гарантия, установка, настройка, обслуживание
– город, если продаёте только в одном городе
– название интернет-магазина

Про цену. Если цену нельзя указать в цифрах, то ради бога — не пишите «выгодная» или «низкая» цена. Ведь если это неправда — пострадает ваш авторитет. В таком случае лучше написать нижнюю планку, например «цена от ____» или «по оптовым ценам», «по цене производителя».

Title

Идеальный тайтл содержит:

  • название товара — для подтверждения, что человек нашёл нужный товар
  • город — в котором покупатель желает товар купить. Если продаёте по всей России, город можно не указывать.
  • имя компании — для брендовых запросов, например «Купить iPhone X в Связном».

Title не резиновый. Поисковики показывают только первые несколько символов, остальные отрезают. Поэтому всю важную информацию старайтесь поместить в первые 60 символов. Если название товара будет длинным, то следующие за ней атрибуты: город, название интернет-магазина — будут не видны в названии сниппета. Поэтому эти атрибуты можно продублировать в описании — в Description.

Description

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

Яндекс.Справка — Метатег Description

Поэтому идеальное мета-описание содержит:

  • стоимость или цену «от»
  • важную информацию о товаре, которой нет в Title — например артикул, бренд
  • город и имя компании — на случай, если эти значения не покажутся в тайтле из-за длинного названия товара
  • информацию о доставке и оплате
  • преимущества, например — бесплатная упаковка, монтаж, настройка
  • призывы к действию — «Закажите», «Оформите», «Звоните»

Шаблон Title
%%title%% — купить в Краснодаре в интернет-магазине %%sitename%%

Шаблон Description
Цена — от %%cf__price%% ₽. %%ct_product_cat%% в Краснодаре оптом и в розницу. Самовывоз и доставка по России. Гарантия качества. Бесплатная упаковка. Заказывайте в интернет-магазине «%%sitename%%».

Переменная %%ct_product_cat%% выводит категорию товара.

Настройка Title и Description карточки товаров в Yoast SEO

Настройка Title и Description карточки товаров в Yoast SEO
В мета-теги карточки товара можно вывести цену. Но будьте внимательны, если на товар нет цены — например, она рассчитывается по запросу — то для таких позиций следует изменить заголовки вручную. Или через плагин импорта, например WP All Import.

Неправильный пример вывода цены в Title товара

Шаблон ничего не вывел — фраза «Купить по цене ₽» — дурацкая. Надо исправить вручную.

Настройка Title и Description для категорий

Убрать «Архивы» из названия категорий WooCommerce

Настройка Title и Description категории товаров в Yoast SEO

Название и описание категории

Yoast SEO: шаблон Title и Description для категории товаров

Номер страницы пагинации в Title

Номер страницы пагинации в Title

Настройка Title и Description для страницы «Контакты»

Быстрые ссылки в выдаче по названию компании

Быстрые ссылки в выдаче по названию компании

Быстрые ссылки в выдаче по общему запросу «магазин сантехники»

Быстрые ссылки в выдаче по общему запросу «магазин сантехники»
В настройках Yoast – заполним дескрипшн вручную, а тайтл сделаем максимально простым.

 

Контакты - магазин %%sitename%%

Description:
☎ Звоните: +7 905 477‑23-46 🕑 Часы работы: ежедневно с 10:00 до 19:00 📍 Краснодар, ул. Домбайская, д. 4/1 📩 contact@konditerproffi.ru

Настройки YOAST SEO для страницы «Контакты»

Настройки YOAST SEO для страницы «Контакты»
Если требуется ручное заполнение мета-тегов, то для ускорения процесса используйте импорт мета-тегов. Используйте плагины WP All Import и дополнение к нему — Yoast WordPress SEO Add-On.
 

Сообщение Как настроить Yoast SEO для интернет-магазина появились сначала на Веб-студия Юсота.


Source: usota.ru seo