Creating Unique SQLAlchemy Engine for Each User in Flask with Oracle

Answered using ChatGPT 4o by ChatGPT4o

Question:

Используется flask, sqlalchemy и oracle GLOBAL TEMPORARY TABLE с опцией ON COMMIT PRESERVE ROWS. SQLALCHEMY_DATABASE_URI одинаков для всех пользователей. Как создать уникальный engine?

Answer:

Для создания уникального SQLAlchemy engine для каждого пользователя в контексте использования Flask, SQLAlchemy и Oracle Global Temporary Table с опцией ON COMMIT PRESERVE ROWS, можно воспользовать��я следующими подходами:

  1. Использование Flask-Scoped Sessions: Flask-SQLAlchemy предоставляет возможность создания сессий, которые привязаны к контексту запроса. Это позволяе�� каждому пользователю име��ь свою собственную сессию и, следователь��о, свой собственный engine.

  2. Создание уникального engine д��я каждого пользователя: Вы можете создать уникальны�� engine для каждого пользователя, используя идентификатор пользователя или другую уникальную информацию.

Вот пример, как это можно сделать:

1. Использовани�� Flask-Scoped Sessions

from flask import Flask, g
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import scoped_session, sessionmaker

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'oracle+cx_oracle://user:password@host:port/dbname'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# Создание scoped session
Session = scoped_session(sessionmaker(bind=db.engine))

@app.before_request
def before_request():
    g.db_session = Session()

@app.teardown_request
def teardown_request(exception=None):
    g.db_session.remove()

# Пример использования
@app.route('/')
def index():
    # Использование сессии из контекста запроса
    session = g.db_session
    # Ваши операции с базой данны��
    return 'Hello, World!'

if __name__ == '__main__':
    app.run()

2. С��здание уникальног�� engine для каждого пользователя

from flask import Flask, g, request
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

app = Flask(__name__)

def get_engine(user_id):
    # Создание уникального URI для каждого пользователя
    uri = f'oracle+cx_oracle://user:password@host:port/dbname?user_id={user_id}'
    return create_engine(uri)

@app.before_request
def before_request():
    user_id = request.headers.get('X-User-ID')  # Предположим, что идентификатор пользователя передается в заголовке
    g.engine = get_engine(user_id)
    g.db_session = sessionmaker(bind=g.engine)()

@app.teardown_request
def teardown_request(exception=None):
    g.db_session.close()

# Пример использования
@app.route('/')
def index():
    # Использование сессии из контекста запроса
    session = g.db_session
    # Ваши операции с базой данных
    return 'Hello, World!'

if __name__ == '__main__':
    app.run()

В обоих примерах мы используе�� контекст запроса Flask (g) для хранения сессии, которая будет уникальной для каждого запроса. В первом примере мы используем scoped_session, чтобы автоматическ�� управлять сессиями для каждого запроса. Во втором примере мы создаем уникальный engine для каждого пользователя на основе их идентификатор��.