Я бы рекомендовал использовать INSERT...ON DUPLICATE KEY UPDATE
.
Если вы используете INSERT IGNORE
, тогда строка на самом деле не будет вставлена, если она приведет к дублированию ключа. Но оператор не будет генерировать ошибку. Вместо этого он генерирует предупреждение. Эти случаи включают в себя:
PRIMARY KEY
или UNIQUE
. NOT NULL
. Если вы используете REPLACE
, MySQL фактически выполняет DELETE
, а внутри INSERT
, у которого есть некоторые неожиданные побочные эффекты:
REPLACE
. DELETE
выполняются без необходимости. исправление: оба REPLACE
и INSERT...ON DUPLICATE KEY UPDATE
являются нестандартными, запатентованными изобретениями специфичный для MySQL. ANSI SQL 2003 определяет оператор MERGE
, который может решить одну и ту же потребность (и многое другое), но MySQL не поддерживает инструкцию MERGE
.
Пользователь попытался отредактировать это сообщение ( изменение было отклонено модераторами). Редактирование попыталось добавить утверждение о том, что INSERT...ON DUPLICATE KEY UPDATE
вызывает выделение нового идентификатора автоматического инкремента. Это правда, что новый идентификатор сгенерирован , но он не используется в измененной строке.
См. Демонстрацию ниже, протестированную с Percona Server 5.5.28. Конфигурационная переменная innodb_autoinc_lock_mode=1
(по умолчанию):
mysql> create table foo (id serial primary key, u int, unique key (u));
mysql> insert into foo (u) values (10);
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 10 |
+----+------+
mysql> show create table foo\G
CREATE TABLE `foo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`u` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
mysql> insert into foo (u) values (10) on duplicate key update u = 20;
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 20 |
+----+------+
mysql> show create table foo\G
CREATE TABLE `foo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`u` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
Вышеописанное показывает, что оператор IODKU обнаруживает дубликат и вызывает обновление для изменения значения u
. Обратите внимание, что AUTO_INCREMENT=3
указывает, что идентификатор был сгенерирован, но не использовался в строке.
В то время как REPLACE
удаляет исходную строку и вставляет новую строку, генерируя и новый идентификатор автоинкремента:
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 20 |
+----+------+
mysql> replace into foo (u) values (20);
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 3 | 20 |
+----+------+
Вы можете использовать pkgutil.walk_packages
:
from pkgutil import walk_packages
possible_packages = [module for _, module, _ in walk_packages()]