Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ANYDATA type #521

Open
gtlawton opened this issue Jan 13, 2021 · 2 comments
Open

Support for ANYDATA type #521

gtlawton opened this issue Jan 13, 2021 · 2 comments

Comments

@gtlawton
Copy link

I have used cx_oracle to push and pull user data type structures to an AQ successfully. However, I have not had complete success with the ANYDATA data type. I can push a user data type message onto an ANYDATA queue with success. When I query the record natively (i.e. from the data column in the queue table) I can see that the content (within the ANYDATA column ) is of the enqueued user data type and using the Oracle function CAST I can read out the data. However, dequeueing ANYDATA messages seems to be a non-starter as it seems impossible to use newobject() against the datatype:

msgTypeAnydata = cn.gettype("SYS.ANYDATA") <<== this works
msg = msgTypeAnydata.newobject() <<== this fails

I have only been able to dequeue ANYDATA messages via stored procedures which then locate the object. The essential elements of the stored procedure is:

address AQMGR.EVENT_MSG_TYPE;
deq_address ANYDATA;

DBMS_AQ.DEQUEUE(  queue_name  =>  'aqmgr.event_queue',      payload  =>  deq_address);

IF (deq_address.GetTypeName() = 'AQMGR.EVENT_MSG_TYPE') THEN
   num_var := deq_address.GetObject(address)

So the above dequeues an ANYDATA message into the payload variable deq_address before the payload is evaluated and the user type "gotten" from the anydata variable (and put into "address"). The procedure returns the user data type object in it's entirety and extraction of the object contents can ensue successfully.

The cx_oracle portion is

msgType = cn.gettype("EVENT_MSG_TYPE")
msg = msgType.newobject()

cur = cn.cursor()
cur.prepare("BEGIN deq(:a); END; ")

cur.execute(None, [msg])
cn.commit()

print(msg.NAME)

This all works.

The procedure "deq" returns into :a the object of the relevant type. NAME is one of the object type variables:

CREATE OR REPLACE TYPE event_msg_type AS OBJECT (
name CHAR(20),
current_status NUMBER(5),
next_status NUMBER(5)
);
/

It's cx 8.1 (Windows 10) on Oracle 19c (Linux)

Is my understanding correct that ANYDATA is not fully supported as an object type? Will it ever be?

@anthony-tuininga
Copy link
Member

You are correct that ANYDATA is not currently supported. We don't have any current plans to support it, but will discuss this internally. Thanks for the suggestion!

@gtlawton
Copy link
Author

Thanks for the response.

ANYDATA is extremely powerful and enables us to update object types without having to rebuild queues. This provides us a way of disassociating any changes from the queue availability which provides high levels of system/application availability. Using Python methods is extremely elegant and being able to unpack types based upon their inherent type within the Python code would be ideal.

All the best.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants