Erro na Exportação de Dados

Boa tarde!

Estou tentando fazer a exportação de dados, através do menu Configurações > Ferramentas > Exportação de Dados, e quando faço as seleção das informações que desejo que saia no arquivo, o sistema dá o seguinte erro:

UnexpectedValueException
The stream or file “/var/www/html/ieducar/storage/logs/laravel-2021-02-22.log” could not be opened in append mode: failed to open stream: Permission denied

Alguém já passou por isso e pode ajudar?

Teste dar permissão de escrita na pasta do projeto:
sudo chmod -R 777 pasta_do_projeto

Não dar certo, não é permissão, também mudo o dono da pasta para servidor web e mesmo assim o erro continua, creio que seja bug.

Esse erro é porque não está sendo possível escrever o log nessa pasta. Dá uma verficada nas permissões, se tem permissão de escrita na pasta ou no arquivo .log.

Oi @tiago.camargo fiz o ajuste e retornou outro erro:
InvalidArgumentException

O disco [pgsql] não possui um driver configurado.

Boa tarde @tiago.camargo Segui sua dica e alterei a permissão da pasta de logs. Mas aí me deparei com o mesmo erro citado pelo @Linex: InvalidArgumentException
Disk [pgsql] does not have a configured driver.

Poderia me ajudar? Por favor?!

Parece ser algo relacionado a essas configurações, i-educar/filesystems.php at 2.6 · portabilis/i-educar · GitHub, que não possui uma unidade pgsql configurada.

Ou talvez aqui, i-educar/database.php at 2.6 · portabilis/i-educar · GitHub , não esteja pegando as configurações corretas.

Vou ver com o pessoal aqui se eles têm alguma ideia!

Olá !

UPDATE no próximo post

Acredito que o problema está no arquivo config/queue.php e na forma como o Job é criado em app/Jobs/DatabaseToCsvExporter.php.

A exportação utiliza job e no Laravel o arquivo queue.php serve pra você apontar as conexões padrões que podem ser utilizadas em jobs.

Estou sem instalação ativa pra constatar, mas aqui vai uma dica pra vocês: tentem adicionar uma chave pgsql nas conexões do queue.php e verifiquem se funciona. Ficaria mais ou menos assim:

    'connections' => [
 
        'sync' => [
            'driver' => 'sync',
        ],
 
        'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'retry_after' => 90,
        ],
 
        'pgsql' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'retry_after' => 90,
        ],

Eu não recomendo renomear a chave database, pois podem existir outros jobs que usam esta conexão.

Identifiquei ainda que a linha 107 do DatabaseToCsvExporter.php cria uma variável $sftp obtendo o nome da conexão do model (que é por padrão pgsql por estender o Model.php padrão do Laravel e não ter sido modificado).

Mais abaixo na linha 120, essa variável é utilizada no comando Storage::disk($sftp) o que causa o erro, pois não existe um storage com o nome de conexão pgsql, apenas uma database.

1 curtida

Olá!

Há um problema quando o SAVE gera o arquivo temporário, ao criar ele fica armazenado em /tmp/, porem o PHP não tem acesso direto aos arquivos do /tmp/, se tentar gerar esse arquivo dentro do storage do laravel, o postgres não tem permissão.

Além do Storage::disk($sftp) sendo chamado sem o driver pgsql.

Uma solução é gerar o arquivo sem precisar do SAVE usando o Eloquent ou DB do laravel.

Após uma análise mais profunda, identifiquei que o PostgreSQL, com o comando COPY TO, pega o resultado da query de exportação e gera o CSV na pasta /tmp/ com um nome em formato de hash. Assim quem gera o CSV é o PostgreSQL diretamente, acionado pelo método $manager->unprepared()

O que é feito pela facade Storage logo abaixo é a criação de um novo arquivo local (para ser público), com um nome legível, tendo como conteúdo o CSV gerado pelo PostgreSQL. Em seguida o CSV gerado pelo PostgreSQL é apagado.

Para que isso funcione precisa existir um filesytem com acesso ao / (root) do servidor, pois o método Storage:get() utiliza caminhos relativos em relação ao filesystem acessado. Esse filesystem deve possuir o nome pgsql. Segue abaixo exemplo de configuração a ser incluída no arquivo config/filesystems.php dentro de disks:

        'pgsql' => [
            'driver' => 'local',
            'root' => '/',
        ],

Isso deve resolver o erro sem nenhum outra mudança. Entretanto pode não ser uma boa prática ter um driver apontado diretamente para a raiz do servidor.

Se esta solução resolver o problema, recomendo a criação de uma issue no GitHub a fim de criarmos este disk no filesystem apontando para /tmp/ e então modificarmos a linha do get para obter somente o arquivo: Storage::disk($sftp)->get($file)

Anteriormente esse arquivo era acessado através de SFTP usando uma string de conexão sftp:host, por isso o nome da variável ($sftp). Ao se conectar no host ele tinha acesso a pasta /tmp/ e então funcionava. Depois foi removido o SFTP e utilizado apenas o driver que vem do nome da conexão com o banco.

Por favor, assim que alguém puder testar, favor informar neste post.

1 curtida

O problema do save só deve ocorrer se você comentar as linhas do facade Storage. Dessa forma o arquivo não será gerado e por isso deve causar o erro.

Tenta essa solução: i-educar/DatabaseToCsvExporter.php at 2.6 · ivenspontes/i-educar · GitHub

Se resolver eu faço um PR