Lançado Adianti Framework 7.6!
Clique aqui para saber mais
Uso de Schema no PostgreSQL Olá a todos. Este é meu primeiro post neste fórum. Sou iniciante no PHP e no framework. Ainda estou na fase de avaliação e estudos de viabilidade de migraçao de meu ERP para este framework. Utilizo o banco de dados PostgreSQL e tenho 2 empresas representadas por "schemas". Além do schema "public" que é padrão e imutável, onde armazeno as tabelas comuns às empresas, tenho os sche...
EF
Uso de Schema no PostgreSQL  
Fechado
Olá a todos.

Este é meu primeiro post neste fórum. Sou iniciante no PHP e no framework. Ainda estou na fase de avaliação e estudos de viabilidade de migraçao de meu ERP para este framework.

Utilizo o banco de dados PostgreSQL e tenho 2 empresas representadas por "schemas".
Além do schema "public" que é padrão e imutável, onde armazeno as tabelas comuns às empresas, tenho os schemas "emp1" e "emp2" para armazenar as tabelas específicas de cada empresa, como: clientes, fornecedores, produtos, pedidos, etc.
Ocorre que no PgSQL tenho que passar o schema junto com o nome da tabela, na sintaxe "schema.tabela" para poder usá-las. O problema é que nas classes de modelos do framework temos que declarar o nome da tabela na constante TABLENAME, mas como posso fazer isto dinamicamente se o nome da tabela muda conforme a empresa selecionada ?
Hoje no meu ERP utilizo instruções diretas para o banco, exemplo:
"SELECT * FROM emp1.clientes WHERE cliente_id = '1'", onde o 'emp1.clientes' vem de uma varável.
Hoje estou usando sub classes e quero saber se tem outra forma mais prática, pois deste modo tenho que criar duas classes a mais para cada tabela do bano de dados e conforme a quantidade de tabelas torna-se inviável trabalhar desta forma, ainda mais se adicionar mais empresas ao sistema.

Exemplo de como estou fazendo:

Na pasta /app/model tenho 3 arquivos:

1) Cliente.class.php

  1. <?php
  2. class Cliente extends TRecord
  3. {
  4.     const PRIMARYKEY 'id';
  5.     const IDPOLICY   'max'// {max, serial}
  6.     ...metodos da classe...
  7. }
  8. ?>


2) Cliente1.class.php

  1. <?php
  2. class Cliente1 extends Cliente
  3. {
  4.    const TABLENAME  'emp1.cliente';
  5. }
  6. ?>


3) Cliente2.class.php

  1. <?php
  2. class Cliente2 extends Cliente
  3. {
  4.    const TABLENAME  'emp2.cliente';
  5. }
  6. ?>


Grato,

Eduardo Fernandes

Curso completo Meu Negócio Pronto
Use para si, ou transforme em um negócio: Inclui aulas e códigos-fontes
Gestor de conteúdo (SITE) + Loja Virtual (E-Commerce) + Emissor de Notas para infoprodutos


Meu negócio pronto Quero me inscrever agora!

Comentários (10)


FC

A impressão que eu tenho (não conheço seu sistema) mas é que a modelagem de dados esta errada, vc deveria ter uma tabela empresa e dentro um identificar dizendo que é empresa 1,2,3,4 assim ficaria muito mais fácil até na manutenção.
EF

Eu tenho esta tabela no meu sistema, apenas estou ilustrando a forma como eu tenho que declarar o nome da tabela no modelo. Será que estamos falando da mesma coisa ?
FC

Puxa desculpa Eduardo entendi agora desse jeito não tem como vc gravar numa TSession no login do seu sistema em qual schema irá trabalhar e concatenar na model?
EF

Não precisa se desculpar, Tudo bem !
O problema é justamente este. Não tem como passar um valor a uma constante (TABLENAME) vindo de uma variável ou TSession, Temos que declarar explicitamente no código, então a única forma que encontrei foi criar subclasses. Como citei acima, sou novato no PHP e talvez tenha outra forma de atribuir um valor a uma constante de outra forma.
FC

Tem varias opções pode usar um arquivo ini, mas também pode incluir o trecho da class (TABLENAME) do arquivo com o include ou até mesmo reescrever toda class com fwrite.
EF

OK Felipe. Obrigado pelas dicas.
Abrs.
PD

Oi Eduardo,

Se são duas empresas totalmente diferentes, poderiam ser bancos totalmente separados, ficando mais fácil a seleção dinâmica (TTransaction::open).

Mas se são duas empresas da mesma (Ex: filiais com CNPJs próprios), sendo que é necessário tirar relatórios consolidados, clientes, produtos e fornecedores poderiam ser únicos, e pedidos poderia ter chave estrangeira para a tabela de empresas (que representa em qual filial ocorreu a venda).

att,
Pablo
EF

Olá Pablo.

Grato pelas sugestões, mas não se aplicam no meu caso.
Eu tenho um sistema desktop que gerencia várias empresas no mesmo
banco de dados, onde eu separo as tabelas de cada empresa em "schemas" e como terei que usar os dois sitemas em conjunto, até que o sistema web fique pronto, não tenho como fazer de outra forma.
Eu modifiquei os métodos getEntity() das classes TRecord e TRepository
para chamar o metodo getEntityName() de uma nova classe que criei chamada TRecord2, a fim de retornar o nome da entidade no padrão "schema.table" necessário no PostgreSQL,

Grato,
Eduardo Fernandes
PD

Oi Edurado,

Tudo bem, mas você terá de tomar cuidado quando atualizar a versão do framework.

Att,
Pablo
RK

Olá Eduardo,

Tive o mesmo problema que o seu, então encontrei esse post no fórum, o qual não me auxiliou.
Posteriormente consegui resolver o problema, segue então a solução:

  1. <?php
  2. /**
  3.  * SystemUnit Active Record
  4.  * @author  <your-name-here>
  5.  */
  6. define('PREFIXO',  TSession::getValue('prefixo'));
  7. class SystemUnit extends TRecord
  8. {    
  9.     const TABLENAME PREFIXO 'system_unit';
  10.     const PRIMARYKEY 'id';
  11.     const IDPOLICY =  'max'// {max, serial}
  12.     
  13.         
  14.     /**
  15.      * Constructor method
  16.      */
  17.     public function __construct($id NULL$callObjectLoad TRUE)
  18.     {
  19.         parent::__construct($id$callObjectLoad);
  20.         parent::addAttribute('name');
  21.     }
  22. }
  23. ?>