JPype и JayDeBeAPI возвращают jpype._jclass.java.lang.Long

Я использую JayDeBeAPI в PySpark (API-интерфейс Apache Spark Python), и вот начало моего кода (обратите внимание, что я фактически запускаю все это через интерактивную оболочку с PySpark).

import jaydebeapi
import jpype

conn = jaydebeapi.connect('org.apache.phoenix.jdbc.PhoenixDriver',
                  ['jdbc:phoenix:hostname', '', ''])

Я запрашиваю Apache Phoenix, который является SQL-интерфейсом для Apache HBase.

Вот мой код Python для запроса SQL:

curs = conn.cursor()
curs.execute('select "username",count("username") from "random_data" GROUP BY "username"')
curs.fetchall()

Вывод, который я получаю, будет таким для всех строк:

(u'Username', <jpype._jclass.java.lang.Long object at 0x25d1e10>)

Как я могу это исправить, чтобы он действительно отображал значение этого возвращаемого столбца (count столбец)?

На странице типов данных Apache Phoenix тип данных count столбец BIGINT, который сопоставлен с java.lang.Long, но по какой-то причине jpype не отображает результат.

Я получил JayDeBeAPI 0.1.4 и JPype 0.5.4.2 python setup.py install когда я их скачал.

3 ответа

Решение

Объект, возвращаемый JPype, является Python-версией Java. java.lang.Long учебный класс. Чтобы получить ценность из этого, используйте value атрибут:

>>> n = java.lang.Long(44)
>>> n
<jpype._jclass.java.lang.Long object at 0x2377390>
>>> n.value
44L

JayDeBeApi содержит дикт (_DEFAULT_CONVERTERS) отображает типы, которые он распознает, в функции, которые преобразуют значения Java в значения Python. Этот дикт можно найти в нижней части __init__.py в исходном коде JayDeBeApi. BIGINT не включается в этот документ, поэтому объекты этого типа базы данных не отображаются из объектов Java в значения Python.

Довольно легко изменить JayDeBeApi, чтобы добавить поддержку BIGINTs. Изменить __init__.py файл, который содержит большую часть кода JayDeBeApi и добавляет строку

    'BIGINT': _java_to_py('longValue'),

к _DEFAULT_CONVERTERS ДИКТ.

Добавление к ответу Люка: в случае, если изменение источника нецелесообразно, вы можете добавлять конвертеры во время выполнения.

import jaydebeapi
from jaydebeapi.dbapi2 import _DEFAULT_CONVERTERS, _java_to_py
_DEFAULT_CONVERTERS.update({'BIGINT': _java_to_py('longValue')})

Это устранило проблемы, которые у меня возникали при использовании jabdebeapi с Vertica.

Автор JayDeBeApi добавляет, что этот метод может нуждаться в изменении для очень больших целых чисел через метод toString () Java BigInteger и затем функцию int() Python: https://github.com/baztian/jaydebeapi/issues/6

Другие вопросы по тегам