我有两个名为 movimiento (id_operacion,id_pago,importe)和票证(id_movimiento,id_localidad,nro_ticket,precio,impreso,id_movimiento_anterior)的表格,票证表格后插入触发器,用于从保存序列值的名为 funcion 的表中指定 nro_ticket 值。
这里是插入前触发器:
create or replace TRIGGER "TICKETS4_TST"."TRG_B_I_TICKET"
BEFORE INSERT ON TICKET REFERENCING NEW AS NEW
FOR EACH ROW
DECLARE
ticket NUMBER;
BEGIN
ticket := OBTENER_NUMERO_TICKET(SUBSTR(:new.id_localidad,0,9));
:new.nro_ticket := ticket;
END;
获取nro_ticket值的函数:
create or replace FUNCTION obtener_numero_ticket (id_fun IN VARCHAR2)
RETURN NUMBER
IS
nro_ticket NUMBER;
BEGIN
SELECT seq_ticket into nro_ticket FROM funcion where id_funcion = id_fun;
RETURN (nro_ticket + 1);
END obtener_numero_ticket;
这里是插入后的触发器:
create or replace TRIGGER "TICKETS4_TST"."TRG_A_I_TICKET"
AFTER INSERT ON TICKET REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
UPDATE funcion SET seq_ticket = :new.nro_ticket WHERE id_funcion= SUBSTR(:new.id_localidad,0,9);
END;
这是SQLAlchemy代码:
sql_movimientos = """INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('%s', '%s', '%s')
RETURNING id_movimiento INTO :id_movimiento"""
sql_tickets = """INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('%s', '%s', '%s',
'%s', '%s')
RETURNING nro_ticket INTO :nro_ticket"""
with db.session as session:
try:
cursor = session.connection().connection.cursor()
nuevo_id_movimiento = cursor.var(NUMBER)
nuevo_nro_ticket = cursor.var(NUMBER)
print sql_movimientos % (
movimiento.operacion, movimiento.pago, movimiento.importe)
session.execute(sql_movimientos % (
movimiento.operacion, movimiento.pago, movimiento.importe),
{'id_movimiento': nuevo_id_movimiento})
nuevo_id_movimiento = int(nuevo_id_movimiento.getvalue())
except Exception, e:
session.rollback()
raise e
try:
print sql_tickets % (nuevo_id_movimiento,
ticket.localidad.id, ticket.precio, ticket.impreso,
ticket.movimiento_anterior)
session.execute(sql_tickets % (nuevo_id_movimiento,
ticket.localidad.id, ticket.precio, ticket.impreso,
ticket.movimiento_anterior),
{'nro_ticket': nuevo_nro_ticket})
nuevo_nro_ticket = int(nuevo_nro_ticket.getvalue())
print nuevo_nro_ticket
except Exception, e:
session.rollback()
raise e
这就是sqlalchemy翻译查询的方式:
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO :id_movimiento
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('5725976', '------------------', '100',
'0', '')
RETURNING nro_ticket INTO :nro_ticket
17 << nro_ticket value
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO :id_movimiento
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('5725977', '-------------', '100',
'0', '')
RETURNING nro_ticket INTO :nro_ticket
17 << nro_ticket value
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO :id_movimiento
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('5725978', '----------------', '100',
'0', '')
RETURNING nro_ticket INTO :nro_ticket
17 << nro_ticket value
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO :id_movimiento
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('5725979', '--------------', '100',
'0', '')
RETURNING nro_ticket INTO :nro_ticket
17 << nro_ticket value
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO :id_movimiento
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('5725980', '--------------', '100',
'0', '')
RETURNING nro_ticket INTO :nro_ticket
17 << nro_ticket value
但是如果在SQLDeveloper中执行与匿名块相同的操作,我会得到正确的值:
declare
id_movimiento number;
nro_ticket number;
begin
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO id_movimiento;
DBMS_OUTPUT.put_line(id_movimiento);
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES (id_movimiento, '------------------', '100',
'0', '')
RETURNING nro_ticket INTO nro_ticket;
DBMS_OUTPUT.put_line(nro_ticket);
INSERT INTO movimiento (id_operacion, id_pago, importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO id_movimiento;
DBMS_OUTPUT.put_line(id_movimiento);
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES (id_movimiento, '--------------------', '100',
'0', '')
RETURNING nro_ticket INTO nro_ticket;
DBMS_OUTPUT.put_line(nro_ticket);
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO id_movimiento;
DBMS_OUTPUT.put_line(id_movimiento);
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES (id_movimiento, '---------------------', '100',
'0', '')
RETURNING nro_ticket INTO nro_ticket;
DBMS_OUTPUT.put_line(nro_ticket);
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO id_movimiento;
DBMS_OUTPUT.put_line(id_movimiento);
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES (id_movimiento, '--------------------', '100',
'0', '')
RETURNING nro_ticket INTO nro_ticket;
DBMS_OUTPUT.put_line(nro_ticket);
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('639086', '566365', '100')
RETURNING id_movimiento INTO id_movimiento;
DBMS_OUTPUT.put_line(id_movimiento);
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES (id_movimiento, '---------------------', '100',
'0', '')
RETURNING nro_ticket INTO nro_ticket;
DBMS_OUTPUT.put_line(nro_ticket);
end;
哪个输出:
5725981
17 << nro_ticket value
5725982
18 << nro_ticket value
5725983
19 << nro_ticket value
5725984
20 << nro_ticket value
5725985
21 << nro_ticket value
所以我认为问题是SQLALchemy,但我不明白为什么它不起作用。
答案 0 :(得分:0)
根据您发布的代码,对我而言,您不清楚如何创建SQLAlchemy
session
。无论如何,既然我的代码看起来很好,我已经对Oracle数据库进行了试验并且它有效。我就是这样做的,
通过SQLAlchemy
创建了2个表格(可能您已直接完成)。
In [2]:
class Movimiento(Base):
__tablename__ = 'movimiento'
id_movimiento = Column(Integer, primary_key=True)
id_operacion = Column(Integer)
id_pago = Column(Integer)
importe = Column(Integer)
In [3]:
class Ticket(Base):
__tablename__ = 'ticket'
nro_ticket = Column(Integer, primary_key=True)
id_movimiento = Column(Integer)
id_localidad = Column(Integer)
precio = Column(Integer)
impreso = Column(Integer)
id_movimiento_anterior = Column(Integer)
直接创建序列
create sequence movimiento_seq;
create sequence ticket_seq;
create or replace trigger movimiento_trigger
before insert on movimiento
for each row
begin
select movimiento_seq.nextval into :new.id_movimiento from dual;
end;
create or replace trigger ticket_trigger
before insert on ticket
for each row
begin
select ticket_seq.nextval into :new.nro_ticket from dual;
end;
然后会议:
engine = create_engine('oracle://test:test@localhost:1521/orcl')
Base.metadata.create_all(engine)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
获取代码并使其成为一个函数,
from cx_Oracle import NUMBER
sql_movimientos = """INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('%s', '%s', '%s')
RETURNING id_movimiento INTO :id_movimiento"""
sql_tickets = """INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('%s', '%s', '%s',
'%s', '%s')
RETURNING nro_ticket INTO :nro_ticket"""
#with session as session:
def ins_mov_tick(movimiento, ticket):
try:
cursor = session.connection().connection.cursor()
nuevo_id_movimiento = cursor.var(NUMBER)
nuevo_nro_ticket = cursor.var(NUMBER)
print sql_movimientos % (
movimiento.id_operacion, movimiento.id_pago, movimiento.importe)
session.execute(sql_movimientos % (
movimiento.id_operacion, movimiento.id_pago, movimiento.importe),
{'id_movimiento': nuevo_id_movimiento})
nuevo_id_movimiento = int(nuevo_id_movimiento.getvalue())
except Exception, e:
session.rollback()
raise e
try:
print sql_tickets % (nuevo_id_movimiento,
ticket.id_localidad, ticket.precio, ticket.impreso,
ticket.id_movimiento_anterior)
session.execute(sql_tickets % (nuevo_id_movimiento,
ticket.id_localidad, ticket.precio, ticket.impreso,
ticket.id_movimiento_anterior),
{'nro_ticket': nuevo_nro_ticket})
nuevo_nro_ticket = int(nuevo_nro_ticket.getvalue())
print nuevo_nro_ticket
except Exception, e:
session.rollback()
(因为我正在使用上面创建的类Movimiento
和Ticket
,而您正在使用一些更复杂的类结构,所以您也会看到一些小修改。)
然后每次我运行该功能时,我都会看到票号递增:
In [21]:
ins_mov_tick(movimiento, ticket)
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('1', '2', '45')
RETURNING id_movimiento INTO :id_movimiento
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('3', '17', '45',
'1', '4')
RETURNING nro_ticket INTO :nro_ticket
3
In [23]:
ins_mov_tick(movimiento, ticket)
INSERT INTO movimiento (id_operacion, id_pago,
importe)
VALUES ('1', '2', '45')
RETURNING id_movimiento INTO :id_movimiento
INSERT INTO ticket (id_movimiento, id_localidad,
precio, impreso,
id_movimiento_anterior)
VALUES ('4', '17', '45',
'1', '4')
RETURNING nro_ticket INTO :nro_ticket
4
我没有创建表格funcion
或触发器,因为我认为这对您的问题不重要。
无论如何,从这个漫长的解释来看,我只想说你的代码应该没问题,而我发现它不适合你的唯一原因就是你必须处理{{{ 1}}(基本上,因为我不太了解你是怎么做到的,所以我不知道它是从哪里来的)。另一种可能性是我误解了一切。
希望它有所帮助。