PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Suporte SQLAlchemy de esquemas Postgres


bem, há algumas maneiras de fazer isso e depende de como seu aplicativo está estruturado. Aqui está a maneira mais básica:
meta = MetaData(schema="client1")

Se a maneira como seu aplicativo é executado é um "cliente" por vez em todo o aplicativo, você terminou.

Mas o que pode estar errado com isso aqui é que todas as Tabelas desse MetaData estão nesse esquema. Se você quiser que um aplicativo dê suporte a vários clientes simultaneamente (geralmente o que significa "multilocatário"), isso seria complicado, pois você precisaria criar uma cópia dos MetaData e copiar todos os mapeamentos para cada cliente. Essa abordagem pode ser feita, se você realmente quiser, a maneira como funciona é acessar cada cliente com uma classe mapeada específica como:
client1_foo = Client1Foo()

e nesse caso você estaria trabalhando com a receita "nome da entidade" em http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityName em conjunto com sometable.tometadata() (consulte http://docs.sqlalchemy.org/en/latest/core/metadata.html#sqlalchemy.schema.Table.tometadata).

Então, digamos que realmente funciona com vários clientes dentro do aplicativo, mas apenas um de cada vez por encadeamento. Bem, na verdade, a maneira mais fácil de fazer isso no Postgresql seria definir o caminho de pesquisa quando você começar a trabalhar com uma conexão:
# start request

# new session
sess = Session()

# set the search path
sess.execute("SET search_path TO client1")

# do stuff with session

# close it.  if you're using connection pooling, the
# search path is still set up there, so you might want to 
# revert it first
sess.close()

A abordagem final seria substituir o compilador usando a extensão @compiles para inserir o nome "schema" nas instruções. Isso é factível, mas seria complicado, pois não há um gancho consistente para todos os lugares em que a "Tabela" é gerada. Sua melhor aposta provavelmente é definir o caminho de pesquisa em cada solicitação.