Модуль Python teradatasql работает только при написании сценариев, но не при выполнении кода - PullRequest
0 голосов
/ 07 октября 2019

У меня возникла странная проблема при использовании пакета teradatasql (установленного из pypi). Я использую следующий код (назовем его pytera.py) для запроса к базе данных:

from dotenv import load_dotenv
import pandas as pd
import teradatasql

# Load the database credentials from .env file
_ = load_dotenv()
db_host = os.getenv('db_host')
db_username = os.getenv('db_username')
db_password = os.getenv('db_password')


def run_query(query):
    """Run query string on teradata and return DataFrame."""
    if query.strip()[-1] != ';':
        query += ';'

    with teradatasql.connect(host=db_host, user=db_username,
                         password=db_password) as connect:
        df = pd.read_sql(query, connect)
    return df

Когда я импортирую эту функцию в интерпретатор IPython / Python или в Блокнот Jupyter, я могу выполнять запросы так же хорошо, какИтак:

import pytera as pt

pt.run_query('select top 5 * from table_name;')

Однако, если я сохраняю приведенный выше код в файле .py и пытаюсь запустить его, я получаю сообщение об ошибке большую часть времени (не всегда). Ниже приведено сообщение об ошибке.

E   teradatasql.OperationalError: [Version 16.20.0.49] [Session 0] [Teradata SQL Driver] Hostname lookup failed for None
E    at gosqldriver/teradatasql.(*teradataConnection).makeDriverError TeradataConnection.go:1046
E    at gosqldriver/teradatasql.(*Lookup).getAddresses CopDiscovery.go:65
E    at gosqldriver/teradatasql.discoverCops CopDiscovery.go:137
E    at gosqldriver/teradatasql.newTeradataConnection TeradataConnection.go:133
E    at gosqldriver/teradatasql.(*teradataDriver).Open TeradataDriver.go:32
E    at database/sql.dsnConnector.Connect sql.go:600
E    at database/sql.(*DB).conn sql.go:1103
E    at database/sql.(*DB).Conn sql.go:1619
E    at main.goCreateConnection goside.go:229
E    at main._cgoexpwrap_e6e101e164fa_goCreateConnection _cgo_gotypes.go:214
E    at runtime.call64 asm_amd64.s:574
E    at runtime.cgocallbackg1 cgocall.go:316
E    at runtime.cgocallbackg cgocall.go:194
E    at runtime.cgocallback_gofunc asm_amd64.s:826
E    at runtime.goexit asm_amd64.s:2361
E   Caused by lookup None on <ip address redacted>: server misbehaving

Я использую Python 3.7.3 и teradatasql 16.20.0.49 в Ubuntu (WSL) 18.04.

Возможно, не случайно я столкнулся с подобной проблемойпри попытке аналогичного рабочего процесса в Windows (с использованием пакета teradata и установленных драйверов Teradata Python). Работает, когда я подключаюсь в интерпретаторе или в Jupyter, но не в скрипте. В случае с Windows ошибка:

E teradata.api.DatabaseError: (10380, '[08001] [Teradata][ODBC] (10380) Unable to establish connection with data source. Missing settings: {[DBCName]}')

У меня такое ощущение, что мне чего-то не хватает, но я нигде не могу найти решение этой проблемы.

Ответы [ 2 ]

1 голос
/ 07 октября 2019

Спасибо равиоли за свежие глаза. Оказывается, проблема заключалась в загрузке переменных окружения с использованием dotenv. Мой модуль находится в пакете Python (отдельная папка), а мои файлы сценариев и .env находятся в рабочем каталоге.

dotenv успешно считывает переменные среды (.env в моем рабочем каталоге), когда я запускаюкод в моем исходном посте, построчно, в интерпретаторе или в Jupyter. Однако, когда я запускаю тот же код в сценарии, он не находит в файле .env в моем рабочем каталоге. Это будет отдельный вопрос, на который мне нужно будет найти ответ.

import teradatasql
import pandas as pd


def run_query(query, db_host, db_username, db_password):
    """Run query string on teradata and return DataFrame."""
    if query.strip()[-1] != ';':
        query += ';'

    with teradatasql.connect(host=db_host, user=db_username,
                         password=db_password) as connect:
        df = pd.read_sql(query, connect)
    return df

Код ниже теперь отлично работает в скрипте:

import pytera as pt
from dotenv import load_dotenv()

_ = load_dotenv()
db_host = os.getenv('db_host')
db_username = os.getenv('db_username')
db_password = os.getenv('db_password')

data = pt.run_query('select top 5 * from table_name;', db_host, db_username, db_password)

0 голосов
/ 07 октября 2019

Похоже, ваш клиент не может найти сервер Teradata, поэтому вы видите, что DBCName отсутствует ошибка. Это должно быть «системное имя» вашего сервера Teradata (то есть TDServProdA).

Пара вещей, которые нужно попробовать:

  1. Если вы пытаетесь подключиться напрямую с именем хоста, попробуйте отключить обнаружение COP в вашем соединении с этим флагом: cop = false. Подробнее

  2. Попробуйте обновить файл hosts в локальной системе. Из документации:

Изменение хостов Файл

Если ваш сайт не использует DNS, вы должны определить IP-адрес и имя базы данных Teradata для использования. в системном файле hosts на компьютере.

  1. Найдите файл hosts на компьютере. Этот файл обычно находится в следующей папке:% SystemRoot% \ system32 \ drivers \ etc
  2. Откройте файл с помощью текстового редактора, например Блокнота.
  3. Добавьте следующую записьк файлу: xxx.xx.xxx.xxx sssCOP1, где xxx.xx.xxx.xxx - это IP-адрес, а где sss - имя базы данных Teradata.

  4. Сохранить файл hosts.

Ссылка 1
Ссылка 2

...