欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

MySQLdb插入数据失败?insert data failed using MySQLdb?

程序员文章站 2022-06-05 12:45:34
...

python mysql 插入失败 conn.execute(, )之后 需要加一句: conn.commit() 有事务处理都要这句,很多地方没有提到。。不知道他们的代码怎么成功的- - 亲,就是这么简单。。 MySQLdb插入数据失败?insert data failed using MySQLdb? 现在项目用的是mySQL数

python mysql 插入失败

conn.execute(…, …)之后

需要加一句:

conn.commit()

有事务处理都要这句,很多地方没有提到。。不知道他们的代码怎么成功的- -

亲,就是这么简单。。

MySQLdb插入数据失败?insert data failed using MySQLdb?

现在项目用的是mySQL数据库,起初,我选择了pymysql作为驱动。后来网上浏览发现用MySQLdb还是蛮多的,于是就换了,pymysql也好久没人维护了。说说问题吧,就是执行insert的时候,总是失败,却没有抛出什么异常,而且还一直堵着mySQL。

发现一个重要的点,就是在执行玩execute之后要commit一下才行。

具体方法有三:

1、在sql语句后加一个COMMIT命令

cursor.execute(‘insertinto?user?(id,?name)?values?(1,?‘luchanghong);COMMIT;’)2、给数据库连接conn预定一个commit

conn?=?MySQLdb.connect(host?=?‘localhost’,?user?=?‘root’,?passwd?=?‘root’,?db?=?‘test’)conn.autocommit(1)3、在释放数据库连接之前commit

conn?=?MySQLdb.connect()cursor.execute(‘insertinto?…’)cursor.close()conn.commit()conn.close()

三种方法我都验证过了,均可以

MySQLdb插入数据失败?insert data failed using MySQLdb?

现在项目用的是mySQL数据库,起初,我选择了pymysql作为驱动。后来网上浏览发现用MySQLdb还是蛮多的,于是就换了,pymysql也好久没人维护了。说说问题吧,就是执行insert的时候,总是失败,却没有抛出什么异常,而且还一直堵着mySQL。

在公司火急火燎的,估计都晕乎了,所以也没搞出来结果。下班在地铁用手机上网查一下,发现一个重要的点,就是在执行玩execute之后要commit一下才行。具体方法有三:

1、在sql语句后加一个COMMIT命令

cursor.execute('insert into user (id, name) values (1, 'luchanghong);COMMIT;')

2、给数据库连接conn预定一个commit

conn = MySQLdb.connect(host = 'localhost', user = 'root', passwd = 'root', db = 'test')
conn.autocommit(1)

3、在释放数据库连接之前commit

conn = MySQLdb.connect()
cursor.execute('insert into ...')
cursor.close()
conn.commit()
conn.close()

PS:我用的是第三种方法,其他两个还没来得及验证,有兴趣的测试一下吧

  • 方案一:使用 ignore 关键字
  • 方案二:使用 replace into
  • 方案三:ON DUPLICATE KEY UPDATE?

方案一:使用 ignore 关键字

如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用:

insert?ignore?into table_name(email,phone,user_id) values(‘test9@163.com’,’99999′,’9999′),这样当有重复记

录就会忽略,执行后返回数字0,还有个应用就是复制表,避免重复记录:

insert?ignore?into table(name)? select? name from table2

方案二:使用 replace into

replace的语法格式为:

1. replace into table_name(col_name, …) values(…)

2. replace into table_name(col_name, …) select …

3. replace into table_name set col_name=value, …

算法说明:

REPLACE的运行与INSERT很相像,但是如果旧记录与新记录有相同的值,则在新记录被插入之前,旧记录被删除,即:

1.????尝试把新行插入到表中

2.????当因为对于主键或唯一关键字出现重复关键字错误而造成插入失败时:

从表中删除含有重复关键字值的冲突行

再次尝试把新行插入到表中

旧记录与新记录有相同的值的判断标准就是:表有一个PRIMARY KEY或UNIQUE索引,否则,使用一个REPLACE语句没有意义

。该语句会与INSERT相同,因为没有索引被用于确定是否新行复制了其它的行。

返回值:

REPLACE语句会返回一个数,来指示受影响的行的数目。该数是被删除和被插入的行数的和。

受影响的行数可以容易地确定是否REPLACE只添加了一行,或者是否REPLACE也替换了其它行:检查该数是否为1(添加)或

更大(替换)。

示例:

eg:(phone字段为唯一索引)

replace ?into table_name(email,phone,user_id) values(‘test569′,’99999′,’123′)

另外:在 SQL Server 中可以这样处理:

if not exists (select phone from t where phone= ’1′)

insert into t(phone, update_time) values(’1′, getdate())

else

update t set update_time = getdate() where phone= ’1′

更多信息请看:http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#replace

方案三:ON DUPLICATE KEY UPDATE

如?上所写,你也可以在INSERT INTO…..后面加上 ON DUPLICATE KEY UPDATE方法来实现。

如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引

或PRIMARY KEY中出现重复值,

则执行旧行UPDATE。例如,如果列a被定义为UNIQUE,并且包含值1,则以下两个语句具有相

同的效果:

mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)

->ON DUPLICATE KEY UPDATE c=c+1;

mysql>UPDATE table SET c=c+1 WHERE a=1;

如果行作为新记录被插入,则受影响行的值为1;如果原有的记录被更新,则受影响行的值为2。

注释:如果列b也是唯一列,则INSERT与此UPDATE语句相当:

mysql>?UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;

如果a=1 OR b=2与多个行向匹配,则只有一个行被更新。通常,您应该尽量避免对带有多个唯一关键字的表使用ON DUPLICATE KEY子句。

您可以在UPDATE子句中使用VALUES(col_name)函数从INSERT…UPDATE语句的INSERT部分引用列值。

换句话说,如果没有发生重复关键字冲突,则UPDATE子句中的VALUES(col_name)可以引用被插入的

col_name的值。本函数特别适用于多行插入。VALUES()函数只在INSERT…UPDATE语句中有意义,其它时候

会返回NULL。

mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)

-> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

本语句与以下两个语句作用相同:

mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)

-> ON DUPLICATE KEY UPDATE c=3;

mysql> INSERT INTO table (a,b,c) VALUES (4,5,6)

-> ON DUPLICATE KEY UPDATE c=9;

当您使用ON DUPLICATE KEY UPDATE时,DELAYED选项被忽略。

示例:?这个例子是我在实际项目中用到的:是将一个表的数据导入到另外一个表中,数据的重复性就得考虑(如下)。

唯一索引为:email

INSERT INTO?table_name1(title,first_name,last_name,email,phone,user_id

,role_id,status,campaign_id)

SELECT?”,”,”,table_name2.email,table_name2.phone,NULL,NULL,’pending’,29

?FROM?table_name2 ?

WHERE?table_name2.status = 1?

ON DUPLICATE KEY UPDATE?table_name1.status = ‘pending’

语句的关键地方,都已高亮出来~

再贴一个例子:

insert into class select * from class1

ON DUPLICATE KEY UPDATE class.course = class1.course

其它关键:DELAYED ?做为快速插入,并不是很关心失效性,提高插入性能。

IGNORE ?只关注主键对应记录是不存在,无则添加,有则忽略。

更多信息请看:??http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#insert

?特别说明:在MYSQL中UNIQUE 索引将会对null字段失效,也就是说(a字段上建立唯一索引):

insert into test(a) values(null)

insert into test(a) values(null)

是可以重复插入的(联合唯一索引也一样)。

REF:

sql 插入重复记录和先查询再插入

http://segmentfault.com/q/1010000000260844

MySQL “replace into” 的坑

注:在 MS 架构中,由于是先删后增,会导致 MS 双方 autoId 不一致。

http://blog.xupeng.me/2013/10/11/mysql-replace-into-trap/