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
Надеюсь статья окажется вам полезной.
Добавить комментарий
SELECT, INSERT и DELETE с pymysql
Сегодня разберёмся с классами Python на примере MySQL. Эта база данных достаточно производительная, чтобы обрабатывать большое количество запросов. На ней работают как небольшие сайты, так и корпорации типа Amazon (подробнее с историей этой СУБД можно ознакомиться тут).
Что потребуется:
- Компьютер или ноутбук
- Редактор кода (У меня PyCharm)
- Python версии 3.9 и выше
- Соединение с интернетом
Установка для 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 на хранение внутрь класса, чтобы оно не пропало.
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 (обычная строка), в него мы и подставляем добавляемые значения.
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
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.