Search code examples
pythonjdbcjpypejaydebeapi

Using JPype - How can I access JDBC Meta Data Functions


I'm using JayDeBeAPI which uses JPype to load FileMaker's JDBC driver and pull data.

But I also want to be able to get a listing of all tables in the database.

In the JDBC documentation (page 55) it lists the following functions:

The JDBC client driver supports the following Meta Data functions:

getColumns

getColumnPrivileges

getMetaData

getTypeInfo

getTables

getTableTypes

Any ideas how I might call them from JPype or JayDeBeAPI?

If it helps, here's my current code:

import jaydebeapi
import jpype

jar = r'/opt/drivers/fmjdbc.jar'
args='-Djava.class.path=%s' % jar
jvm_path = jpype.getDefaultJVMPath()
jpype.startJVM(jvm_path, args)

conn = jaydebeapi.connect('com.filemaker.jdbc.Driver',
        SETTINGS['SOURCE_URL'], SETTINGS['SOURCE_UID'], SETTINGS['SOURCE_PW'])
curs = conn.cursor()

#Sample Query:
curs.execute("select * from table")
result_rows = curs.fetchall()

Update:

Here's some progress and it seems like it should work, but I'm getting the error below. Any ideas?

> conn.jconn.metadata.getTables()
*** RuntimeError: No matching overloads found. at src/native/common/jp_method.cpp:121

Solution

  • Ok, thanks to eltabo and Juan Mellado I figured it out!

    I just had to pass in the correct parameters to match the method signature.

    Here's the working code:

    import jaydebeapi
    import jpype
    
    jar = r'/opt/drivers/fmjdbc.jar'
    args='-Djava.class.path=%s' % jar
    jvm_path = jpype.getDefaultJVMPath()
    jpype.startJVM(jvm_path, args)
    
    conn = jaydebeapi.connect('com.filemaker.jdbc.Driver',
            SETTINGS['SOURCE_URL'], SETTINGS['SOURCE_UID'], SETTINGS['SOURCE_PW'])
    results = source_conn.jconn.getMetaData().getTables(None, None, "%", None)
    
    #I'm not sure if this is how to read the result set, but jaydebeapi's cursor object
    # has a lot of logic for getting information out of a result set, so let's harness
    # that.
    table_reader_cursor = source_conn.cursor()
    table_reader_cursor._rs = results
    read_results = table_reader_cursor.fetchall()
    #get just the table names
    [row[2] for row in read_results if row[3]=='TABLE']