MySql INSERT SELECT одним запросом

В этой заметке хочу рассказать об одной особенности использования SQL операторов INSERT SELECT. Конечно для подобных вещей мне бы выделить отдельную категорию, и назвать её, скажем, SQL, но так как статей на эту тему у меня пока мало поместим её сюда.

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

Вопрос в том как это сделать лучше и проще, да желательно одним запросом?

В MySql для этого в операторе INSERT можно использовать оператор SELECT следующим образом (здесь мы копируем данные из одной таблицы в другую, имеющую такую же структуру):

INSERT INTO 
	`some_table` (`fld1`,`fld2`,`fld3`)
SELECT 
	`some_table2`.
`fld1`, `some_table2`.`fld2`, `some_table2`.`fld3` FROM `some_table2` WHERE `some_table2`.`fld` > 100;

Стоит заметить, что операция INSERT SELECT может быть произведена в рамках одной таблицы.

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

INSERT INTO 
	`some_table` (`fld1`,`fld2`,`fld3`)
SELECT 
	`src`.`fld1`,
    `src`.`fld2`,
    `src`.`fld3` 
FROM 
	`some_table`  AS `src`
WHERE 
	`src`.`fld` > 100;

В случае, если вы работаете с одной таблицей и, если она имеет поле с уникальным индексом, его дублирование нужно как-то обрабатывать. Обычно уникальное поле это исскуственный первичный ключ с AUTO_INCREMENT, и как правило в этой ситуации его можно просто не указывать — система его создаст самостоятельно. Но, если у вас есть ещё уникальные индексы, то при копировании необходимо о них позаботиться. Например как вариант следующим образом (`unic_int_field` — уникальное целочисленное поле):

INSERT INTO 
	`some_table` (`fld1`,`fld2`,`fld3`,`unic_int_field`)
SELECT 
	`src`. `fld1`,
    `src`.`fld2`,
    `src`.`fld3` ,
    (`unic_int_field` + 1)
FROM 
	`some_table`  AS `src`
WHERE 
	`src`.`fld` > 100;

Если поле имеет один из строковых типов данных, то как вариант можно использовать следующий маневр (`unic_name` — уникальное поле с символьным типом данных,`unic_int_field` — уникальное целочисленное поле) :

INSERT
	INTO `some_table` (`name`,`ins_payment`,`description`,`franchise`,`checked_out`)
SELECT
	CONCAT("COPY ", SYSDATE(), " : ", `unic_name`),
	`src`.`fld1`,
    `src`.`fld2`,
    `src`.`fld3` ,
    (`unic_int_field` + 1)
FROM 
	`some_table`  AS `src`
WHERE 
	`src`.`fld` > 100;

Т.е. к строке мы просто конкатенируем «COPY » и текущее дату-время. Таким образом вновь созданное поле с большой долей вероятности будет иметь уникальное значение, и дублирования, и как следствия ошибки запроса не произойдёт. Но что бы система работала более стабильно можно использовать ключевое слово IGNORE. Тогда, если вдруг у вас всё таки, что-то продублируется — ошибки не произойдёт, а MySql сообщит что запрос выполнен, но эффект затронул 0 строк.

А эту ситуацию вы легко обработаете в клиентском коде:

INSERT IGNORE
	INTO `some_table` (`name`,`ins_payment`,`description`,`franchise`,`checked_out`)
SELECT
	CONCAT("COPY ", SYSDATE(), " : ", `unic_name`),
	`src`.`fld1`,
    `src`.`fld2`,
    `src`.`fld3` ,
    (`unic_int_field` + 1)
FROM 
	`some_table`  AS `src`
WHERE 
	`src`.`fld` > 100;

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

Кстати! Примеры выше будут работать даже без использования псевдонимов:

INSERT
	INTO `some_table` (`name`,`ins_payment`,`description`,`franchise`,`checked_out`)
SELECT
	CONCAT("COPY ", SYSDATE(), " : ", `unic_name`),
	`fld1`,
    `fld2`,
    `fld3` ,
    (`unic_int_field` + 1)
FROM 
	`some_table`
WHERE 
    `fld` > 100;

Но в более сложных запросах псевдонимы всё же придётся использовать, в любом случае запрос не должен противоречить синтаксису и правилам SQL

Справка на английском (увы) по INSERT SELECT для MySql

Надеюсь статья окажется вам полезной.

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

SELECT, INSERT и DELETE с pymysql

Сегодня разберёмся с классами Python на примере MySQL. Эта база данных достаточно производительная, чтобы обрабатывать большое количество запросов. На ней работают как небольшие сайты, так и корпорации типа Amazon (подробнее с историей этой СУБД можно ознакомиться тут).

Что потребуется:

  1. Компьютер или ноутбук
  2. Редактор кода (У меня PyCharm)
  3. Python версии 3.9 и выше
  4. Соединение с интернетом

Установка для Windows:

pip install pymysql

Для macOS:

pip3 install pymysql

Установка MySQL

Самый простой способ — задействовать программу OpenServer. Эта программа помогает локально поднимать сервера для сайтов и отображать их в браузере. Мы будем использовать её для быстрого доступа к БД.

1. Скачиваем установочный файл отсюда

2. Запускаем его и следуем всем инструкциям

3. Запускаем OpenServer и ищем внизу флажок:

4. Кликаем на него и выбираем пункт настройки:

5. Ищем в настройках вкладку модули:

6. Если в выпадающем меню «MySQL/MariaDB» выставлено «не использовать», кликаем и выбираем самую последнюю версию СУБД MySQL:

Настройка базы данных MySQL в PhpMyAdmin

Запускаем сервер в OpenServer, наводим на вкладку «дополнительно» и нажимаем на «PhpMyAdmin»:

Дальше вас перекидывает на сайт, где мы вводим логин «root». 
Поле «пароль» остается пустым.

В главном меню нам нужен пункт «создать БД». В этом окне придумываем имя базы данных и нажимаем «создать» (тип кодировки не трогаем, оставляем стандартный). После всех манипуляций у нас есть база данных. Остается создать таблицу внутри:

Придумываем имя таблицы и добавляем несколько столбцов. 
Нам потребуется 4 столбца, добавляем их и нажимаем «вперед»:

Итак, наша база данных готова. Если вы хотите подробнее углубиться в работу с базой данных на MySQL, посмотрите видео тут. 

Создаём класс MySQL на Python

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

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

import pymysql

class MySQL:
    def __init__(self, host, port, user, password, db_name):
        self.connection = pymysql.connect(
            host=host,
            port=port,
            user=user,
            password=password,
            database=db_name,
            cursorclass=pymysql.cursors.DictCursor
        )

С импортами тут все ясно — подключаем нашу библиотеку для работы с MySQL. 

Что такое __init__? Эта конструкция будет срабатывать при создании объекта класса. Внутрь нее мы передаём аргументы для создания подключения к базе данных. Также, мы передаём поле connection на хранение внутрь класса, чтобы оно не пропало.

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

    def add_user(self, name, age, email):
        insert_query = f"INSERT INTO `user` (name, age, email) VALUES ({name}, {age}, {email})"
        with self.connection.cursor() as cursor:
            cursor.execute(insert_query)
            self.connection.commit()

Метод add_user – тут мы будем создавать новую запись с пользователем, передаем его имя, возраст и почту. Внутри insert_query хранится запрос на языке SQL (обычная строка), в него мы и подставляем добавляемые значения. 

Для выполнения запроса используем curcor.execute, а для сохранения — connection.commit.

    def del_user(self, id):
        delete_query = f"DELETE FROM `user` WHERE id = {id}"
        with self.connection.cursor() as cursor:
            cursor.execute(delete_query)
            self.connection.commit()

Метод del_user – тут мы ищем по ID в базе данных человека и удаляем эту строчку.

    def update_age_by_id(self, new_age, id):
        update_query = f"UPDATE `user` SET age = {new_age} WHERE id = {id}"
        with self.connection.cursor() as cursor:
            cursor.execute(update_query)
            self.connection.commit()

В метод update_age_by_id поступают новый возраст человека и его ID, чтобы было можно его найти. 

    def select_all_data(self):
        select_all_rows = f"SELECT * FROM `user`"
        with self.connection.cursor() as cursor:
            cursor.execute(select_all_rows)
            rows = cursor.fetchall()
            return rows

Метод select_all_data делает запрос к базе на получение всех строчек, которые есть в таблице. Результат возвращается в виде объекта, который мы превращаем в список с помощью fetchall. 

    def __del__(self):
        self.connection.close()

Метод __del__ срабатывает, когда объект уничтожается. Это нужно, поскольку по документации pymysql нужно закрывать сессию подключения к БД после окончания работы. Поэтому внутри этого метода мы обращаемся к connection и вызываем метод close.

Весь класс с методами будет выглядеть так:

import pymysql


class MySQL:
    def __init__(self, host, port, user, password, db_name):
        self.connection = pymysql.connect(
            host=host,
            port=port,
            user=user,
            password=password,
            database=db_name,
            cursorclass=pymysql.cursors.DictCursor
        )

    def add_user(self, name, age, email):
        insert_query = f"INSERT INTO `user` (name, age, email) VALUES ('{name}', {age}, '{email}')"
        with self.connection.cursor() as cursor:
            cursor.execute(insert_query)
            self.connection.commit()

    def del_user(self, id):
        delete_query = f"DELETE FROM `user` WHERE id = {id}"
        with self.connection.cursor() as cursor:
            cursor.
execute(delete_query)             self.connection.commit()     def update_age_by_id(self, new_age, id):         update_query = f"UPDATE `user` SET age = {new_age} WHERE id = {id}"         with self.connection.cursor() as cursor:             cursor.execute(update_query)             self.connection.commit()     def select_all_data(self):         select_all_rows = f"SELECT * FROM `user`"         with self.connection.cursor() as cursor:             cursor.execute(select_all_rows)             rows = cursor.fetchall()             return rows     def __del__(self):         self.connection.close()

Использование класса MySQL

Чтобы начать работу с БД через Python, нам надо передать в объект класса MySQL ряд параметров — IP, порт, логин, пароль и название самой базы данных: 

host = '127.0.0.1'
port = 3306
user = 'root'
password = ''
db_name = 'user'

bd = MySQL(host=host, port=port, user=user, password=password, db_name=db_name)

После этого мы сможем обращаться к методам объекта bd.  
Давайте добавим несколько пользователей:

db.add_user('Анна', 26, '[email protected]')
db.add_user('Егор', 19, '[email protected]')

Тем самым мы в таблицу добавили Анну и Егора.

print(db.select_all_data())

Выводим в консоль весь массив данных с помощью метода select_all_data:

[{‘id’: 1, ‘name’: ‘Анна’, ‘age’: 26, ’email’: ‘[email protected]’}, 
{‘id’: 2, ‘name’: ‘Егор’, ‘age’: 19, ’email’: ‘[email protected]’}]

Как это выглядит в PhpMyAdmin:

Удалим пользователя 1 из таблицы:

db.del_user(1)

Проверяем базу данных:

Попробуем поменять возраст второго пользователя:

db.update_age_by_id(12, 2)

Егору было 19 лет, стало 12:

Заключение

Мы разобрали создание базы данных на СУБД MySQL, создали класс на Python для управления базой и добавили несколько полезных методов. Для усвоения материала рекомендуем повторить наши манипуляции, а также написать парочку собственных методов.

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

Полезные ссылки

Документация pymysql: https://pymysql.readthedocs.io/en/latest/

Туториалы по MySQL: https://www.mysqltutorial.org/

Документация MySQL: https://dev.mysql.com/doc/refman/8.0/en/tutorial.html

INSERT Использование предложения WITH в MySQL

Начиная с MySQL v8, у нас есть общие табличные выражения (CTE) или предложение WITH . Недавно я узнал, как использовать предложение WITH в операторе INSERT , подобно INSERT с SELECT . Как всегда, мне нравится делиться тем, что я узнаю, поэтому давайте учиться вместе…

Информационный бюллетень для разработчиков PHP и MySQL

Получите копию моей электронной книги «10 советов по MySQL для всех» , абсолютно бесплатно при подписке на информационный бюллетень OpenLampTech .

Ради простоты (и спокойствия) я использую следующие произвольные данные:

 SELECT * 
FROM auto_test;

Мы можем использовать предложение WITH для генерации значения имени для INSERT :

 WITH rogue_name AS( 
SELECT 'Dillion' AS some_name
)
SELECT * F ПЗУ rogue_name;

✔️ MySQL не требует таблицы, названной в предложении FROM оператора SELECT , как это делают некоторые диалекты SQL.


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

 WITH rogue_name AS( 
SELECT 'Dillion' AS some_name
)
INSERT INTO auto_test
SELECT some_name FROM rogue_name;

Код ошибки: 1064. Ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с «INSERT INTO auto_test SELECT some_name FROM rogue_name» в строке 4

Вы можете видеть, что при этой попытке INSERT была возвращена ошибка с использованием WITH . В этот момент предложение WITH ожидает, что следующим оператором будет SELECT , а в данном запросе это не так.

Однако перемещение предложения WITH между предложением INSERT INTO и оператором SELECT выполняется без ошибок:

 INSERT INTO auto_test (name) 
WITH rogue_name AS(
ВЫБЕРИТЕ 'Диллион' КАК какое-то_имя
)
ВЫБЕРИТЕ какое-то_имя ИЗ имя_мошенника;
 ВЫБРАТЬ * 
ИЗ auto_test;

Это очень удобно, если у вас есть предложение WITH , которое генерирует некоторые данные, необходимые для ВСТАВКИ в другую таблицу. Дайте мне знать, если вы используете предложение WITH для INSERT !

Спасибо, что прочитали этот пост. Пожалуйста, поделитесь им с кем-то еще, кому это тоже понравится.


Джош Отвелл хочет развиваться как разработчик PHP, эксперт по SQL и технический блогер/писатель.

Отказ от ответственности: большинство примеров в этом посте выполняются в среде персональной рабочей станции для разработки/обучения, и не следует считать готовым к производству или готовым . Ваши конкретные цели и потребности могут отличаться. Как всегда, только потому, что вы можете что-то сделать, не означает, что вы должны . Мои мнения являются моими собственными.

Чем еще я могу помочь

  • LoopGenius поможет вам найти клиентов, распространить информацию о вашей подработке и превратить вашу идею в веб-сайт. Используйте код купона: KZGZ3WSP когда вы зарегистрируйтесь сегодня и получите скидку 10%!
  • Узнайте о Google Analytics с помощью этого курса, подготовленного ребятами из The Content Technologist.
  • Нужен хостинг для вашего следующего веб-приложения или сайта WordPress? Я настоятельно рекомендую Hostinger и использую их для хостинга моего нишевого сайта по ловле окуня . Сервис не имеет себе равных.
  • 🔒 5 истин, которые я осознал как разработчик-самоучка
  • Мобильные обои, цифровые загрузки, фотографии, услуги по разработке и контент — все в одном Kofi Shop Страница . Найдите свою следующую цифровую покупку сегодня!

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

Информационный бюллетень для разработчиков PHP и MySQL

Получить копию моей электронной книги, «10 советов по MySQL для всех» , абсолютно бесплатно при подписке на информационный бюллетень OpenLampTech .


📰 Привлеките к своему бренду, продукту или услуге то внимание, которого они заслуживают с доступным размещением объявлений в информационном бюллетене OpenLampTech . Я ценю вашу поддержку!


Вот так:

Нравится Загрузка…

Python MySQL Вставить в таблицу


Python Вставить данные в таблицу Mysql

После создания базы данных и таблицы мы можем начать добавлять информацию .

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

  • В Python запрос SQL должен заключаться в кавычки .
  • Вам необходимо заключить в кавычки строковые значения (текстовые столбцы) внутри SQL-запроса.
  • Вам не нужно кавычки для числовые значения .
  • Имя NULL и ключевые слова DEFAULT нельзя заключать в кавычки.

Используйте команду INSERT INTO , чтобы добавить новые записи в таблицу MySQL.

 ВСТАВИТЬ В имя_таблицы (столбец1, столбец2, столбец3,...)
ЗНАЧЕНИЯ (значение1, значение2, значение3,...)
 

Мы установили пустую таблицу с именем «книги» с тремя столбцами: «идентификатор», «имя» и «цена» в предыдущей главе.

Посмотрите на структуру таблицы:

Имя столбца Тип данных Экстра
идентификатор интервал auto_increment + первичный ключ
имя текст
цена поплавок

Примечание:- Если есть АВТОМАТИЧЕСКОЕ ПРИРАЩЕНИЕ (например, столбец ID ), запрос SQL не должен должны указать это; MySQL автоматически добавляет значение .


Вставить в стол

Метод execute() используется для запуска любого sql-запроса к базе данных mysql.

Свойство rowcount используется для возврата числа затронутых строк , выполненных последними запросами.

commit () метод используется для сохранения всех изменений , сделанных запросами sql, такими как вставка, обновление, удаление записей и так далее.

Примечание: — Вы не сможете получить какие-либо изменения (записать вставку, обновление и удаление) в таблице, если вы пропустите метод commit() .

Пример: — Вставить запись в «книги» таблица:

 import mysql.connector
mydb = mysql.connector.connect(
  хост = "локальный хост",
  пользователь = «имя пользователя»,
  пароль="мой пароль",
  база данных = "моя база данных"
)
мойкурсор = mydb. курсор()
# Вставить запись с помощью обычного SQL-запроса
sql = "ВСТАВИТЬ В книги (название, цена) ЗНАЧЕНИЯ ("поваренная книга Python", 175,50)"
mycursor.execute(sql)
print(mycursor.rowcount, "запись вставлена")
# Вставить запись, используя подготовленный оператор SQL-запроса (рекомендуется)
# Это дает большую безопасность по сравнению с предыдущим
qry = "ВСТАВИТЬ В книги (название, цена) ЗНАЧЕНИЯ (%s, %s)"
val = ("полный справочник по Python", "220")
mycursor.execute(qry, значение)
print(mycursor.rowcount, "запись вставлена")
mydb.commit() 

Выход :-

Вставлена ​​1 запись.
Вставлена ​​1 запись.

После выполнения вышеуказанной программы таблица «books» выглядит так:

ID Имя Цена
1 кулинарная книга питона 175,50
2 полная ссылка на Python 220.00

Важно! : Обратите внимание: mydb. commit() , Изменения должны быть сделаны , иначе таблица не может быть изменена .

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


Вставка нескольких рядов

Метод executemany() используется для одновременной вставки нескольких записей в таблицу.

Второй параметр метода executemany() представляет собой список кортежей , который включает данные, которые должны быть вставлены:

Пример: — Вставьте три записи в «книги» таблицу с данными:

 импорт mysql. connector
mydb = mysql.connector.connect(
  хост = "локальный хост",
  пользователь = «имя пользователя»,
  пароль="мой пароль",
  база данных = "моя база данных"
)
мойкурсор = mydb.курсор()
sql = "ВСТАВИТЬ В книги (название, цена) ЗНАЧЕНИЯ (%s, %s)"
значение = [
 («Сеть Python», 160),
 («Веб-программирование», 70),
 («Интернет с Python», 120)
]
mycursor.executemany(sql, val)
mydb.commit()
print(mycursor.rowcount, "запись вставлена")
 

Выход :-

Вставлена ​​3 запись.




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


Получить последний вставленный идентификатор

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

Свойство lastrowid используется для возврата последнего вставленного идентификатора из таблицы.

Примечание: id из последних вставленных строк возвращается, если вставлено более одной строки.

Пример: — Получить последний вставленный идентификатор:

 import mysql.connector
mydb = mysql.connector.connect(
  хост = "локальный хост",
  пользователь = «имя пользователя»,
  пароль="мой пароль",
  база данных = "моя база данных"
)
мойкурсор = mydb.курсор()
sql = "ВСТАВИТЬ В книги (название, цена) ЗНАЧЕНИЯ (%s, %s)"
val = ("Новая эра питона", 55)
mycursor.execute(sql, значение)
mydb.commit()
print("ID: ", mycursor.lastrowid) 

Выход :-

ID: 6




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