SQLALCHEMY MULTITENANCY (общая таблица)Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 SQLALCHEMY MULTITENANCY (общая таблица)

Сообщение Anonymous »

Я настраиваю новое многопользовательское приложение и задаюсь вопросом, как обрабатывать доступ к базе данных.
Я использую базу данных Postgres. Приложение Flask читает из базы данных. Задание префекта использует ту же базу кода и регулярно обновляет базу данных. /Отсутствие арендаторов в базе данных «Одна схема на арендатор» довольно сложно, мы решили пойти с общими таблицами (общие таблицы имеют столбец venant_id ).
Как мы может переехать в другую систему баз данных, мы не хотим использовать функцию RLS Postgres. Для этой настройки общего стола-мультленсии в Sqlalchemy?! Я нашел старую мультиальную библиотеку , но она была архивирована в 2022 году, а последний коммит был 9 лет назад: https://github.com/mwhite/multialchemy
Я начал Написание моего собственного множественного контекстного манагер (используя глобальные критерии ORM), но это довольно сложно сделать ... < /p>

Код: Выделить всё

class HasClientColumn(object):
"""Mixin that identifies a class as having a tenant/client column"""
client_id = Column(BigInteger, nullable=False)

class Testerle(HasClientColumn, Base):
__tablename__ = "testerle"
id = Column(BigInteger, primary_key=True, autoincrement=True)
secret = Column(Text)

class Testerle2(HasClientColumn, Base):
__tablename__ = "testerle2"
id = Column(BigInteger, primary_key=True, autoincrement=True)
secret = Column(Text)

db_sessionmaker = sessionmaker(
autocommit=False, autoflush=False, bind=db_engine, future=True
)

def get_client_scoped_db_session(client_id: int):
session = db_sessionmaker()

# Overwrite execute method so nobody uses it without ORM
session.execute = lambda x, *args, **kwargs: _raise(
Exception(
"client_scoped_db_session not meant to be used with execute command (unsafe). Use ORM!"
)
)

# Docs: https://docs.sqlalchemy.org/en/14/orm/session_events.html#do-orm-execute-global-criteria
@event.listens_for(session, "do_orm_execute")
def _do_orm_execute(orm_execute_state):
if (
orm_execute_state.is_select
and not orm_execute_state.is_column_load
and not orm_execute_state.is_relationship_load
):
orm_execute_state.statement = orm_execute_state.statement.options(
with_loader_criteria(
HasClientColumn,
lambda cls: cls.client_id == client_id,
include_aliases=True,
)
)

return session

@contextmanager
def with_client_scoped_db_session(client_id: int):
session = False
try:
logging.debug(f"Establishing DB session for client {client_id}")
session = get_client_scoped_db_session(client_id)
yield session
session.commit()
except Exception as e:
logging.exception(f"Exception in with_client_scoped_db({client_id}): {e}")
if session:
session.rollback()
raise e
finally:
logging.debug(f"Closing DB session for client {client_id}")
if session:
session.close()
< /code>
Это работает довольно хорошо, когда просто вызывает такие вещи, как < /p>
with with_client_scoped_db_session(1) as session:
session.query(Testerle).all()
< /code>
Но всякий раз, когда я делаю присоединение, как < /p>
with with_client_scoped_db_session(1) as session:
session.query(Testerle, Testerle2.secret).join(Testerle2, Testerle.id == Testerle2.id).all()
< /code>
он сталкивается с моим пользовательским исключением, говоря, что метод выполнения запрещен (client_scoped_db_session not meant to be used with execute command (unsafe). Use ORM!
). Конечно, я не мог бы перезаписать session.execute , но тогда каждый разработчик мог бы использовать сеанс клиента для запуска SQL на всех данных клиентов (например, session.execute (text («select * from testerle»). Fetchall (например ) ) -> небезопасно.
Любые идеи, как реализовать стабильную и безопасную многопользовательство с общими таблицами, используя Sqlalchemy без постгресса RLS?

Подробнее здесь: https://stackoverflow.com/questions/794 ... ared-table
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»