генерировать аннотированные сущности doctrine2 из схемы db

Можно ли генерировать объекты Doctrine 2 с соответствующими аннотациями docblock из существующей схемы базы данных?


person waigani    schedule 31.10.2010    source источник
comment
Подумайте о том, чтобы не делать этого. Вы создадите лучшие объекты, если создадите их с нуля специально для своего приложения. Сопоставьте их с аннотациями позже.   -  person rojoca    schedule 02.11.2010


Ответы (4)


Мне пришлось внести эти изменения, чтобы приведенный выше код работал.

<?php 
use Doctrine\ORM\Tools\EntityGenerator;
ini_set("display_errors", "On");
$libPath = __DIR__; // Set this to where you have doctrine2 installed
// autoloaders
require_once $libPath . '/Doctrine/Common/ClassLoader.php';

$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', $libPath);
$classLoader->register();

$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
$classLoader->register();

$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__);
$classLoader->register();

// config
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(__DIR__ . '/Entities'));
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');


$connectionParams = array(
    'path' => 'test.sqlite3',
    'driver' => 'pdo_sqlite',
);

$em = \Doctrine\ORM\EntityManager::create($connectionParams, $config);

// custom datatypes (not mapped for reverse engineering)
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('set', 'string');
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');

// fetch metadata
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
    $em->getConnection()->getSchemaManager()
);
$em->getConfiguration()->setMetadataDriverImpl($driver);
$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory($em);
$cmf->setEntityManager($em); 
$classes = $driver->getAllClassNames();
$metadata = $cmf->getAllMetadata(); 
$generator = new EntityGenerator();
$generator->setUpdateEntityIfExists(true);
$generator->setGenerateStubMethods(true);
$generator->setGenerateAnnotations(true);
$generator->generate($metadata, __DIR__ . '/Entities');
print 'Done!';
?>

и конфигурация подключения mysql, например:

$connectionParams = array(
    'driver' => 'pdo_mysql',
    'host' => 'localhost',
    'port' => '3306',
    'user' => 'root',
    'password' => 'root',
    'dbname' => 'database',
    'charset' => 'utf8',
);
person dminer    schedule 18.03.2011
comment
Спасибо! Это действительно сработало. (Нет, как программа, включенная в доктрину). - Хотя я использовал ваш код только из-под $connectionParams, потому что я не уверен в вашей настройке среды. Например, функция register(); явно не определена. В любом случае большой +1! - person vbence; 08.07.2011
comment
Это отлично работает для меня ... Большой +1 для вас. Для других, у кого такая же проблема, используйте этот ответ, все остальные не будут работать... - person Tareq; 28.01.2012
comment
@dminer: Ваш скрипт успешно работает и сэкономил мне много времени, так как я новичок в Doctrine. Этот скрипт создал объект из базы данных с помощью методов установки и получения, исключая операции CRUD. Что делать дальше, если я хочу добавить все основные операции CRUD в этот объект. Обратите внимание, что мой проект — это не симфонический проект, а простой основной проект. - person neeraj; 03.01.2013

Да, это возможно, хотя типы данных РСУБД не полностью поддерживаются, поэтому вам, возможно, придется немного поиграть с кодом, прежде чем использовать его в своем проекте. Это не так просто, как Doctrine 1.x, но все же довольно просто. Вот пример кода, который я использовал сам (правильно создайте папки перед его использованием)

use Doctrine\ORM\Tools\EntityGenerator;

ini_set("display_errors", "On");

$libPath = __DIR__ . '/../lib/doctrine2';

// autoloaders
require_once $libPath . '/Doctrine/Common/ClassLoader.php';

$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', $libPath);
$classLoader->register();

$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
$classLoader->register();

$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__);
$classLoader->register();

// config
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(__DIR__ . '/Entities'));
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');


$connectionParams = array(
    'dbname' => 'xx',
    'user' => 'root',
    'password' => '',
    'host' => 'localhost',
    'driver' => 'pdo_mysql',
);

$em = \Doctrine\ORM\EntityManager::create($connectionParams, $config);

// custom datatypes (not mapped for reverse engineering)
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('set', 'string');
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');

// fetch metadata
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver(
    $em->getConnection()->getSchemaManager()
);
$classes = $driver->getAllClassNames();
foreach ($classes as $class) {
    //any unsupported table/schema could be handled here to exclude some classes
    if (true) {
        $metadata[] = $cmf->getMetadataFor($class);
    }
}

$em->getConfiguration()->setMetadataDriverImpl($driver);
$cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory($em);

$generator = new EntityGenerator();
$generator->setUpdateEntityIfExists(true);
$generator->setGenerateStubMethods(true);
$generator->setGenerateAnnotations(true);
$generator->generate($metadata, __DIR__ . '/Entities');

print 'Done!';
person Daniel S. W.    schedule 02.11.2010
comment
Ошибка в строке $metadata[] = $cmf-›getMetadataFor($class); Почему он пытается получить родителя класса, который еще не существует? Я имею в виду, что это имена сущностей, которые собираются реконструировать. - person Timmo; 03.12.2010

Я реализовал новую команду для достижения этого >https://github.com/umpirsky/doctrine2/blob/master/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesDbCommand.php

Просто добавьте это так:

$cli->addCommands(array(
// DBAL Commands
new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),

// ORM Commands
new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesDbCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),

)); $кли->выполнить();

person umpirsky    schedule 03.12.2010

По состоянию на https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php , создание сущностей уже поддерживается интерфейсом командной строки Doctrine по умолчанию.

person Ocramius    schedule 19.01.2012