В приведенном ниже описании conn.rollback () не удаляет вставку кадра данных "a".Подскажите, пожалуйста, есть ли хороший способ сделать так, чтобы вставлялась только буква "a"?
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))
edit:
Будет ли эффективна реализация динамической генерации нижеприведенного кода?Для каждой финальной таблицы есть буферная таблица.Как только статус в таблице транзакций обновляется до 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