Flask -SQLAlchemy для соединения двух разных postgres баз данных - PullRequest
0 голосов
/ 26 февраля 2020

Отчаянно ищите помощи здесь, применили исправления, предложенные в различных блогах, но без помощи.

Требование. Мне нужно подключиться к двум различным postgres базам данных. одна первичная и другая для загрузки только 5 моделей (представления базы данных) из вторичной базы данных.

Мы используем IAMprofiles для подключения к базе данных. Это приводило к сбою аутентификации PAM каждые 15 минут, чтобы исправить это, мы использовали Creator (lambda) для управления соединениями.

В настоящее время проблема в том, что первичное соединение работает нормально, но вторичное не распознается и все еще ищет схему в первичной базе данных, а не во вторичной.

Попробовано ниже:

Первичное соединение с использованием SQLALCHEMY_DATABASE_URI. Второстепенное использование связываний. Использовал привязку на моделях для определения БД, которую следует использовать вместе с опцией «autoload_with»

И по какой-то причине исключение говорит, что переданный механизм не имеет атрибута с именем «drivername»

Любая помощь будет принята с благодарностью.

Config file: 

class IAMProfileAPI:
    db_type = 'rds'
    cert_path = 'certificate'
    aws_region = 'region'
    rds_host = 'host'
    rds_port = 5432
    rds_db_name = 'database'
    rds_user = 'database_user'
    rds_ssl_mode = 'verify-ca'
    rds_schema_name = 'target_dbo'
    rds_pwd = ''


def get_IAM_token_api():
    aws_client = boto3.client(IAMProfileAPI.db_type, region_name=IAMProfileAPI.aws_region)
    token = aws_client.generate_db_auth_token(IAMProfileAPI.rds_host, IAMProfileAPI.rds_port, IAMProfileAPI.rds_user)
    return token


def create_sql_engine_api():
    IAMProfileAPI.rds_pwd = get_IAM_token_api()
    conn_strold = f"postgresql+psycopg2://{IAMProfileAPI.rds_host}:{IAMProfileAPI.rds_port}/{IAMProfileAPI.rds_db_name}" \
               f"?sslmode={IAMProfileAPI.rds_ssl_mode}&sslrootcert={IAMProfileAPI.cert_path}"

    conn_str = 'postgresql+psycopg2://{user}:{pw}@{url}/{db}?sslmode={sslmode}&sslrootcert={sslcert}'.\
        format(user=IAMProfileAPI.rds_user, pw=IAMProfileAPI.rds_pwd, url=IAMProfileAPI.rds_host,
                db=IAMProfileAPI.rds_db_name,sslmode=IAMProfileAPI.rds_ssl_mode, sslcert=IAMProfileAPI.cert_path)
    args = dict()
    rds_credentials = {'connect_args': {'user': IAMProfileAPI.rds_user, 'password': get_IAM_token_api()}}
    args.update(rds_credentials)
    return conn_str



class IAMProfile:
    db_type = 'rds'
    cert_path = 'certificate'
    aws_region = 'region'
    rds_host = 'host'
    rds_port = 5432
    rds_db_name = 'database'
    rds_user = 'database_user'
    rds_ssl_mode = 'verify-ca'
    rds_schema_name = 'target_dbo'
    rds_pwd = ''

def create_sql_engine():
    connection_string = f"postgresql+psycopg2://{IAMProfile.rds_host}:{IAMProfile.rds_port}/{IAMProfile.rds_db_name}" \
                        f"?sslmode={IAMProfile.rds_ssl_mode}&sslrootcert={IAMProfile.cert_path}"
    return connection_string


def get_IAM_token():
    aws_client = boto3.client(IAMProfile.db_type, region_name=IAMProfile.aws_region)
    token = aws_client.generate_db_auth_token(IAMProfile.rds_host, IAMProfile.rds_port, IAMProfile.rds_user)
    return token


connection_string = create_sql_engine()
connection_string_api = create_sql_engine_api()
db_schema = 'primary_dbo'
dbo_schema = 'secondary_dbo'
SQLALCHEMY_DATABASE_URI = connection_string
SQLALCHEMY_ENGINE_OPTIONS = {'creator': lambda: psycopg2.connect(database=IAMProfile.rds_db_name,
                                                                 user=IAMProfile.rds_user,
                                                                 host=IAMProfile.rds_host,
                                                                 port=IAMProfile.rds_port,
                                                                 password=get_IAM_token(),
                                                                 sslmode=IAMProfile.rds_ssl_mode,
                                                                 sslrootcert=IAMProfile.cert_path)}
backend_engine = create_engine(connection_string_api)
meta = MetaData(bind=backend_engine)
SQLALCHEMY_BINDS = {
    #db_schema: connection_string
    dbo_schema: connection_string_api
}

SQLALCHEMY_TRACK_MODIFICATIONS = False

Models.py


class LoadTheFields(Model):
    ___bind_key__ = 'dbo_schema'
    __tablename__ = 'loadmainfields'
    table_args__ = {'schema': config.dbo_schema , 'autoload': True, 'autoload_with': backendengine(dbo_schema)}
    id = Column(Integer, primary_key=True)`dbo_schema`





...