SQLAlchemy oracle connect - PullRequest
       16

SQLAlchemy oracle connect

0 голосов
/ 08 февраля 2020

Большинство соединений, которые я вижу, не похожи на тип соединения SQLAlchemy, которое я использую. Мне интересно, есть ли способ отразить этот стиль или его нужно использовать в create_engine. Вот пример моего соединения и класса, который я использую для подключения к определенной таблице c:

from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from flask_restful import Api
from flask_cors import CORS
from flask_jwt_extended import JWTManager
import os
from dotenv import load_dotenv
load_dotenv(verbose=True)

app = Flask(__name__)
CORS(app)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
app.config['JWT_SECRET_KEY'] = os.getenv('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('SQLALCHEMY_DATABASE_URI')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['JWT_BLACKLIST_ENABLED'] = True
app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh']
db = SQLAlchemy(app)
api = Api(app)
jwt = JWTManager(app)

Моя строка URI БД выглядит так:

SQLALCHEMY_DATABASE_URI="oracle+cx_oracle://username:password@db_url/dbName"

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

И теперь класс, с которым я пытаюсь создать соединение:

from App import db


class EventModel(db.Model):
    __tablename__ = 'SCHEMA_NAME.TABLE_NAME'

    RC_ID = db.Column(db.Integer, primary_key=True)
    PRODUCT_ID = db.Column(db.Integer)
    RELEASE_ID = db.Column(db.Integer)
    RCPM_ID = db.Column(db.Integer)
    FIT_DTTM = db.Column(db.String(25))
    DATACTR_ID = db.Column(db.String(10))
    COMMENT_TXT = db.Column(db.String(500))
    DESCR_TXT = db.Column(db.String(300))
    EVENTCMPLT_FLG = db.Column(db.String(1))
    EVENTCMPLTONTM_FLG = db.Column(db.String(1))
    ATTACHMENTS_FLG = db.Column(db.String(1))
    UUID = db.Column(db.Integer)
    URLS = db.Column(db.String(4000))

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

Я попытался присоединить имя схемы также к URI БД I хранить в моей переменной среды. Я всегда получаю эту ошибку:

sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-12505: TNS:listener does not currently know of
        SID given in connect descriptor

Я ценю помощь каждого. Обычно я работаю с postgres, и проект, в который я конвертирую свой обычный метод, использует oracle дБ.

Ответы [ 2 ]

0 голосов
/ 18 марта 2020

Спасибо всем за помощь. Я забыл опубликовать это, и я не могу вспомнить, где я нашел это, но вот как я решил проблему:

oracle_connection_string = 'oracle+cx_oracle://{username}:{password}@' + 
cx_Oracle.makedsn('{hostname}', '{port}', service_name='{service_name}')

app = Flask(__name__)
CORS(app)
app.config['SQLALCHEMY_DATABASE_URI'] = oracle_connection_string.format(
  username=db_user,
  password=db_pw,
  hostname=db_host.split(':')[0],
  port='1521',
  service_name=db
)

Надеюсь, это поможет.

0 голосов
/ 08 февраля 2020

Просто используйте <tns alias> вашей базы данных в конце строки SQLALCHEMY_DATABASE_URI, преобразованной в

engine = db.create_engine('oracle+cx_oracle://username:password@mydb')

, где mydb предполагается равным <tns alias> в пределах вашего TNSNAMES.ORA файл, такой как

mydb=
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = proddb1)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = mycompany.com)
    )
  )
...