0

I am trying to execute a spatial query on an Oracle spatial table via python using the cx_Oracle package.

I can make generic queries successfully, but when I try anything involving a geometry or spatial query, it results in errors.

This is what I have tried:

import cx_Oracle
...

lon = -120.494352
lat = 36.585289

# open a connection to oracle
con = cx_Oracle.connect('myuser/mypass@spatialdb')

# create a cursor
cur = con.cursor()

# Create and populate Oracle objects
typeObj = con.gettype("MDSYS.SDO_GEOMETRY")
elementInfoTypeObj = con.gettype("MDSYS.SDO_ELEM_INFO_ARRAY")
ordinateTypeObj = con.gettype("MDSYS.SDO_ORDINATE_ARRAY")
obj = typeObj.newobject()
obj.SDO_GTYPE = 2001
obj.SDO_SRID = 8307
obj.SDO_ELEM_INFO = elementInfoTypeObj.newobject()
obj.SDO_ELEM_INFO.extend([1, 1, 1])
obj.SDO_ORDINATES = ordinateTypeObj.newobject()
obj.SDO_ORDINATES.extend([lon, lat])
print("Created object", obj)

# set up a distance-calculating sql statement
sql = "select id into :id from spatialtbl s where sdo_nn(s.geometry, :obj, 'sdo_num_res=1', 1) = 'TRUE'"

try:
    # execute the distance sql
    cur.execute(sql, id=id, obj=obj)
    print(f'The id is {id.getvalue()}')
except cx_Oracle.Error as error:
    print(error)

which results in the error:

ORA-01036: illegal variable name/number

Can anyone tell me what I may be doing wrong code-wise or if spatial queries are even possible using Python and cx_Oracle?

0

I think the "select into" was the problem (reserved for pl/sql?).

By doing the following I was able to obtain the answer:

# set up a distance-calculating sql statement
sql = """select id from spatialtbl s where sdo_nn(s.geometry, :ob, 'sdo_num_res=1', 1) = 'TRUE'"""

try:
    # execute the distance sql
    cur.execute(sql, ob=obj)
    id = cur.fetchone()
    print(f'The id is {id}')
except cx_Oracle.Error as error:
    print(error)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.