Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
11
respostas

Erro no comando migrations:migrate

Olá, pessoal. Ao executar o comando vendor\bin\doctrine-migrations migrations:migrate o sistema me retornou o seguinte erro:

[notice] Migrating up to Alura\Doctrine\Migrations\Version20201112102659
[error] Migration Alura\Doctrine\Migrations\Version20201109173746 failed during Pre-Checks. Error: "Provided directory "C:\Users\João\AppData\Local\Temp" does not exist"

In InvalidProxyDirectoryException.php line 17:

  Provided directory "C:\Users\João\AppData\Local\Temp" does not exist


migrations:migrate [--write-sql [WRITE-SQL]] [--dry-run] [--query-time] [--allow-no-migration] [--all-or-nothing [ALL-OR-NOTHING]] [--configuration CONFIGURATION] [--db-configuration DB-CONFIGURATION] [--] [<version>]

No entanto, a pasta informada existe, porém, o nome do usuário é João. Poderia ser este o problema? O que poderia estar incorreto no meu programa que gerou este erro?

Segue abaixo o código do arquivo de migração gerado na última aula:

<?php

declare(strict_types=1);

namespace Alura\Doctrine\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
 * Auto-generated Migration: Please modify to your needs!
 */
final class Version20201112102659 extends AbstractMigration
{
    public function getDescription() : string
    {
        return '';
    }

    public function up(Schema $schema) : void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->addSql('CREATE TABLE Curso (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, nome VARCHAR(255) NOT NULL)');
        $this->addSql('CREATE TABLE curso_aluno (curso_id INTEGER NOT NULL, aluno_id INTEGER NOT NULL, PRIMARY KEY(curso_id, aluno_id))');
        $this->addSql('CREATE INDEX IDX_6F96721A87CB4A1F ON curso_aluno (curso_id)');
        $this->addSql('CREATE INDEX IDX_6F96721AB2DDF7F4 ON curso_aluno (aluno_id)');
        $this->addSql('DROP INDEX IDX_D8448137B2DDF7F4');
        $this->addSql('CREATE TEMPORARY TABLE __temp__Telefone AS SELECT id, aluno_id, numero FROM Telefone');
        $this->addSql('DROP TABLE Telefone');
        $this->addSql('CREATE TABLE Telefone (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, aluno_id INTEGER DEFAULT NULL, numero VARCHAR(255) NOT NULL COLLATE BINARY, CONSTRAINT FK_D8448137B2DDF7F4 FOREIGN KEY (aluno_id) REFERENCES Aluno (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
        $this->addSql('INSERT INTO Telefone (id, aluno_id, numero) SELECT id, aluno_id, numero FROM __temp__Telefone');
        $this->addSql('DROP TABLE __temp__Telefone');
        $this->addSql('CREATE INDEX IDX_D8448137B2DDF7F4 ON Telefone (aluno_id)');
    }

    public function down(Schema $schema) : void
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->addSql('DROP TABLE Curso');
        $this->addSql('DROP TABLE curso_aluno');
        $this->addSql('DROP INDEX IDX_D8448137B2DDF7F4');
        $this->addSql('CREATE TEMPORARY TABLE __temp__Telefone AS SELECT id, aluno_id, numero FROM Telefone');
        $this->addSql('DROP TABLE Telefone');
        $this->addSql('CREATE TABLE Telefone (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, aluno_id INTEGER DEFAULT NULL, numero VARCHAR(255) NOT NULL)');
        $this->addSql('INSERT INTO Telefone (id, aluno_id, numero) SELECT id, aluno_id, numero FROM __temp__Telefone');
        $this->addSql('DROP TABLE __temp__Telefone');
        $this->addSql('CREATE INDEX IDX_D8448137B2DDF7F4 ON Telefone (aluno_id)');
    }
}

Agradeço desde já pela ajuda. Se precisarem de mais alguma informação, basta me avisar.

11 respostas

João, muito provavelmente o problema é o acento sim. Windows tem bastantes problemas com isso.

Você pode mudar o diretório dos proxies para uma pasta que não possua espaço nem acentos. Aqui mostra como fazer isso:

https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/advanced-configuration.html

Olá Vinicius, fiquei com uma dúvida referente às informações contidas no link, ainda sou "iniciante" em programação PHP. A informação que eu deveria mudar seria a:

$config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies');

correto? Mas minha dúvida é a seguinte, eu deveria criar este arquivo contendo o código fornecido no link, ou ele já existe e eu deveria editá-lo? Se tiver de criar, qual seria a pasta correta para inserir o arquivo de configuração? No meu caso, poderia usar a sintaxe:

$config->setProxyDir('D:\Alura\proxyTemp');

Opa, vamos por partes, João.

eu deveria criar este arquivo contendo o código fornecido no link

'/path/to/myproject/lib/MyProject/Proxies' não é um arquivo. É um caminho fictício (repare que começa com "path to my project", ou seja, "caminho para meu projeto").

qual seria a pasta correta para inserir o arquivo de configuração?

O arquivo de configuração é o que você instancia o EntityManager. Ele já existe. Já o caminho para os proxies pode ser o que você preferir.

No meu caso, poderia usar a sintaxe: $config->setProxyDir('D:\Alura\proxyTemp');

Pode sim, João. É exatamente isso aí. :-) Só se lembre de conferir se essa pasta realmente existe você tem permissão de escrita nela. :-D

Então, eu havia entendido que essa parte era o caminho do diretório, que eu deveria especificar, mas devo ter me expressado errado. Eu fiz as alterações no código do arquivo EntityManagerFactory, mas o erro persiste idêntico, ou seja, não alterou o caminho, provavelmente fiz algo errado. Estou tentando identificar o que seria, mas não consegui. Vou postar o código abaixo para análise de vocês. Novamente, peço desculpas caso tenha cometido algum erro de leigo.

<?php

namespace Alura\Doctrine\Helper;

use Doctrine\Common\Cache\ArrayCache;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Tools\Setup;

class EntityManagerFactory
{
    /**
     * @return EntityManagerInterface
     * @throws ORMException
     */


    public function getEntityManager(): EntityManagerInterface
    {
        $cache = new ArrayCache;

        $config = new Configuration;
        $config->setMetadataCacheImpl($cache);
        $driverImpl = $config->newDefaultAnnotationDriver('/path/to/lib/MyProject/Entities');
        $config->setMetadataDriverImpl($driverImpl);
        $config->setQueryCacheImpl($cache);
        $config->setProxyDir('D:\Alura\proxyTemp');
        $config->setProxyNamespace('Alura\Doctrine\Helper\Proxies');

        $config->setAutoGenerateProxyClasses(true);

        $rootDir = __DIR__ . '/../..';
        $configuration = Setup::createAnnotationMetadataConfiguration([$rootDir . '/src'], true);
        $connection = ['driver' => 'pdo_sqlite', 'path' => $rootDir . '/var/data/banco.sqlite'];
        return EntityManager::create($connection, $configuration);
    }
}

João, você não está utilizando sua variável de configuração. Você não está passando ela por parâmetro para a criação do EntityManager. E repara que na variável config você definiu o caminho errado para as entidades.

Vinicius, boa tarde e desculpe por todo o trabalho. Realmente, vi depois só que havia criado o $config e $configuration. No entanto, depois fiz as mudanças, acreditei que estaria correto, porém o problema persiste. Adicionei primeiro apenas o comando $config->setProxyDir(...), mas não funcionou, depois voltei todo o código e fiz a alteração nas entidades, mas não sei se fiz corretamente, porque o problema persiste.

<?php

namespace Alura\Doctrine\Helper;

use Doctrine\Common\Cache\ArrayCache;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Tools\Setup;

class EntityManagerFactory
{
    /**
     * @return EntityManagerInterface
     * @throws ORMException
     */


    public function getEntityManager(): EntityManagerInterface
    {

        /*$cache = new ArrayCache;

        $config = new Configuration;
        $config->setMetadataCacheImpl($cache);
        $driverImpl = $config->newDefaultAnnotationDriver('D:\Alura\projeto-doctrine\src\Entity');
        $config->setMetadataDriverImpl($driverImpl);
        $config->setQueryCacheImpl($cache);
        $config->setProxyDir('D:\Alura\proxyTemp');

        $config->setAutoGenerateProxyClasses(true);*/

        $rootDir = __DIR__ . '/../..';
        $config = Setup::createAnnotationMetadataConfiguration([$rootDir . '/src'], true);
        $config->setProxyDir('D:\Alura\proxyTemp');

        $connection = ['driver' => 'pdo_sqlite', 'path' => $rootDir . '/var/data/banco.sqlite'];
        return EntityManager::create($connection, $config);
    }
}

O que aparece quando você tenta rodar vendor\bin\doctrine orm:generate-proxies?

Segue retorno do comando vendor\bin\doctrine orm:generate-proxies

D:\Alura\projeto-doctrine>vendor\bin\doctrine orm:generate-proxies

 Processing entity "Alura\Doctrine\Entity\Aluno"
 Processing entity "Alura\Doctrine\Entity\Curso"
 Processing entity "Alura\Doctrine\Entity\Telefone"

 Proxy classes generated to "D:\Alura\proxyTemp"

No entanto, ao tentar rodar o migrations:migrate o erro persiste

João, consegue limpar todos os caches do Doctrine e depois tentar de novo? No caso de falha, pode me mandar um print do comando com a saída pra eu ver se encontro algo diferente?

solução!

Vinicius, tentei limpar os caches e efetuar a ação novamente, no entanto o problema continuava a ocorrer. Como não queria perder mais tempo tentando solucionar o problema, achei mais rápido formatar o notebook e alterar o nome do usuário. Depois de configurar todos os parâmetros do PHP e do projeto novamente, fiz o teste e o comando funcionou perfeitamente. Voltei a realizar as aulas. O problema realmente era o acento no nome do usuário.

João, você podia só ter criado outro usuário sem formatar o computador. rsrs

Mas que bom que funcionou. Fica aí a dica de não usar usuários com acento