Подключитесь к базе данных Oracle, используя SQLALCHEMY

Я могу успешно подключиться к базе данных sqlite и получить доступ к конкретной таблице с помощью набора команд ниже.

from sqlalchemy import create_engine, MetaData, Table, and_

from sqlalchemy.sql import select

from pandas import DataFrame 

db = create_engine('sqlite:///path\\database.db')

metadata = MetaData(db)

table = Table('table name', metadata, autoload=True)

Я могу получить данные из базы данных оракула с помощью библиотеки cx_Oracle.

Однако, когда я пытаюсь подключиться к базе данных Oracle в sqlalchemy, я получаю следующую ошибку

NoSuchTableError: <table name>

Я использовал следующие команды:

db = create_engine('oracle://username:password@hostname:1521/instance name',echo='debug')

md = MetaData(bind=db)

t = Table('table name', md, autoload=True,schema='schema name')

Когда я использую следующую команду

t= Table('table name', md, autoload=True,oracle_resolve_synonyms=True)

Я получаю следующую ошибку:

AssertionError: There are multiple tables visible to the schema, you must specify owner

Можете ли вы понять, где именно я иду не так.

Спасибо,

Рохит

6 ответов

Вам больше не нужно импортировать cx_Oracle. Более новая версия модуля sqlalchemy вызывает функцию cx_Oracle.makedsn(). Взглянуть:

from sqlalchemy.engine import create_engine

DIALECT = 'oracle'
SQL_DRIVER = 'cx_oracle'
USERNAME = 'your_username' #enter your username
PASSWORD = 'your_password' #enter your password
HOST = 'subdomain.domain.tld' #enter the oracle db host url
PORT = 1521 # enter the oracle port number
SERVICE = 'your_oracle_service_name' # enter the oracle db service name
ENGINE_PATH_WIN_AUTH = DIALECT + '+' + SQL_DRIVER + '://' + USERNAME + ':' + PASSWORD +'@' + HOST + ':' + str(PORT) + '/?service_name=' + SERVICE

engine = create_engine(ENGINE_PATH_WIN_AUTH)


#test query
import pandas as pd
test_df = pd.read_sql_query('SELECT * FROM global_name', engine)
from sqlalchemy import create_engine
import cx_Oracle

host=hostname
port=port
sid='sid'
user='username'
password='password'
sid = cx_Oracle.makedsn(host, port, sid=sid)

cstr = 'oracle://{user}:{password}@{sid}'.format(
    user=user,
    password=password,
    sid=sid
)

engine =  create_engine(
    cstr,
    convert_unicode=False,
    pool_recycle=10,
    pool_size=50,
    echo=True
)

result = engine.execute('select * from TABLE')

for row in result:
    print row

Это сработало для меня. Объект подключения также может быть создан как

conn = engine.connect()
conn.close()

что позволит закрыть соединение. Это работает, даже если у вас есть туннель к вашей удаленной БД из локального порта.

Предполагая, что у вас есть клиент Oracle на вашем компьютере с действительным файлом tnsnames.ora, это работает для меня:

from sqlalchemy import create_engine
import pandas as pd 
engine = create_engine('oracle://myusername:mypassword@SID')
con = engine.connect()
outpt = con.execute("SELECT * FROM YOUR_TABLE")
df = pd.DataFrame(outpt.fetchall())
df.columns = outpt.keys()
print(df.head())
con.close() 

"... если у вас уже есть строка подключения, которая работает с cx_Oracle":

      import pandas as pd
from sqlalchemy import create_engine
import cx_Oracle

conn_factory = lambda: conn_factory = lambda: cx_Oracle.connect(user=dbuser, password=dbpass, dsn=dsn)

engine = create_engine(
    "oracle://", 
    creator=conn_factory
)

data = pd.read_sql("SELECT 1 FROM DUAL", engine)

https://gist.github.com/DGrady/7fb5c2214f247dcff2cb5dd99e231483?permalink_comment_id=4035380#gistcomment-4035380

Это работает для меня, когда нет tnsnames.ora файл.

user = 'system'
pwd = 'oracle'
dsn = cx_Oracle.makedsn(
    '192.168.1.105', 49161,
    # service_name='your_service_name_if_any'
)
ora_engine = create_engine(f'oracle+cx_oracle://{user}:{pwd}@{dsn}', echo=True)
ora_engine.connect()

Вот слегка отполированная версия ответа @mkarun2.

Предпосылки:

  • Установить пакеты:

    sudo apt установить libaio1

  • Скачать библиотеку Oracle InstantClient

  • Сделать символическую ссылку:

    ln -s libclntsh.so.21.1 libclntsh.so

  • Запустите приложение следующим образом:

    экспорт LD_LIBRARY_PATH=oracle-instantclient/instantclient_21_1 python main.py

Здесь main.py:

      import cx_Oracle
import sqlalchemy as sa


# Use your config
username = 'username'
password = 'security'
hostname = 'localhost'
service_name = 'Xal' or None
port = '1521'


# Tell cx_Oracle where to find the libraries. Optional.
cx_Oracle.init_oracle_client(lib_dir='oracle-instantclient/instantclient_21_1')


# Connection string
oracle_connection_string_fmt = (
    'oracle+cx_oracle://{username}:{password}@' +
    cx_Oracle.makedsn('{hostname}', '{port}', service_name='{service_name}')
)
url = oracle_connection_string_fmt.format(
    username=username, password=password, 
    hostname=hostname, port=port, 
    service_name=service_name,
)

# Create SqlAlchemy Engine
engine: sa.engine.Engine = sa.create_engine(url, echo=True)

Вот как сделать свой первый запрос:

      res: sa.engine.cursor.LegacyCursorResult = engine.execute("SELECT * FROM tablename")
for row in res:
    print(row)

обратите внимание, что запрос не имеет ;в конце ;) Oracle не любит точки с запятой.

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