在下面,conn.rollback()不会删除数据帧“ a”的插入。您能告诉我是否有一种很好的方法可以使“ a”仅插入“ d”吗?
import sqlite3 as sql
import pandas as pd
conn = sql.connect(':memory:')
a = pd.DataFrame(['a','b','c'],columns=['col1'])
d = pd.DataFrame(['d'],columns=['col1'])
a.to_sql('test',con=conn,if_exists='append')
try:
raise()
d.to_sql('test',con=conn,if_exists='append')
except:
print('failed')
conn.rollback()
print(pd.read_sql('select * from test',con=conn))
编辑:
实施以下内容的动态生成是否有效?对于每个最终表,都有一个缓冲表。一旦事务表中的状态更新为1,就会触发触发器,尝试将所有缓冲区表数据放入最终表中。
CREATE TABLE `sql_transactions` (
`id_insert` INTEGER NOT NULL,
'as_of' datetime not null,
`status` INTEGER NOT NULL, -- -1: fail
-- 0: inserting into buffer
-- 1: sending
-- 2: success
primary key (id_insert, as_of)
);
CREATE TABLE "tbl_1" ( 'k' TEXT NOT NULL, 'v' REAL not null, PRIMARY KEY('k') ) WITHOUT ROWID;
CREATE TABLE "tbl_2" ( 'k' TEXT NOT NULL, 'v' REAL not null, PRIMARY KEY('k') ) WITHOUT ROWID;
CREATE TABLE "buffer_tbl_1" ('id_insert' integer, 'k' TEXT NOT NULL, 'v' REAL, PRIMARY KEY('id_insert','k')) WITHOUT ROWID;
CREATE TABLE "buffer_tbl_2" ('id_insert' integer, 'k' TEXT NOT NULL, 'v' REAL, PRIMARY KEY('id_insert','k')) WITHOUT ROWID;
create trigger "into_tbls" after insert on sql_transactions
begin
insert into tbl_1 (k,v) select k, v from buffer_tbl_1 where buffer_tbl_1.id_insert = new.id_insert and new.status = 1;
delete from buffer_tbl_1 where buffer_tbl_1.id_insert = new.id_insert;
insert into tbl_2 (k,v) select k, v from buffer_tbl_2 where buffer_tbl_2.id_insert = new.id_insert and new.status = 1;
delete from buffer_tbl_2 where buffer_tbl_2.id_insert = new.id_insert;
update sql_transactions set status = 2 where new.id_insert = new.id_insert and new.status = 1;
end
create trigger "delete_failure" after insert on sql_transactions
begin
delete from buffer_tbl_1 where buffer_tbl_1.id_insert = new.id_insert and new.status = -1;
delete from buffer_tbl_2 where buffer_tbl_2.id_insert = new.id_insert and new.status = -1;
end
insert into sql_transactions (id_insert,as_of,status) values (0,datetime('now'),0)
insert into buffer_tbl_1 (id_insert,k,v) values (0,"a",1), (0,"b",2)
insert into buffer_tbl_2 (id_insert,k,v) values (0,"c",3), (0,"d",4)
select * from sql_transactions;
select * from buffer_tbl_1;
select * from buffer_tbl_2;
-- successfully move data from the buffer tables to the final tables
insert into sql_transactions (id_insert,as_of,status) values (0,datetime('now'),1)
select * from tbl_1;
select * from tbl_2;
select * from buffer_tbl_1;
select * from buffer_tbl_2;
insert into sql_transactions (id_insert,as_of,status) values (1,datetime('now'),0)
-- allow null gets into the tbl_2 buffer, but prevents insert into tbl_1
insert into buffer_tbl_1 (id_insert,k,v) values (1,"z",1), (1,"y",2)
insert into buffer_tbl_2 (id_insert,k,v) values (1,"x",3), (1,"w",NULL)
insert into sql_transactions (id_insert,as_of,status) values (1,datetime('now'),1)
select * from tbl_1;
select * from tbl_2;
select * from buffer_tbl_1;
select * from buffer_tbl_2; -- bad insert stays in buffer for review
-- this would go in the except statement
insert into sql_transactions (id_insert,as_of,status) values (1,datetime('now'),-1)
select * from tbl_1;
select * from tbl_2;
select * from buffer_tbl_1;
select * from buffer_tbl_2; -- bad insert stays in buffer for review
select * from sql_transactions