运行Doctrine convert-mapping时跳过表

时间:2014-12-11 18:47:21

标签: php mysql doctrine-orm doctrine

我第一次坐下了学说并试图在现有的网站/数据库上使用它的一些命令行工具。我从命令行使用了映射和实体逆向工程工具,想看看它将从php / mysql中的现有网站生成什么类型​​的文件。

但是,它会在任何例外情况下停止。我已经能够为枚举创建一个类型映射,现在就将它们抛出一个字符串,但是现在它阻止了我没有指定主ID密钥的表。我对在链接表中使用主键或复合键的演讲不感兴趣,我只是在学习Doctrine时尝试生成一些输出。

有没有一种方法可以告诉学说跳过抛出异常的表,或者在它们击中它时不停止的情况下通过?我现在只想要一些示例输出,并且不想完全重新考虑复杂的数据库因为看看Doctrine可以做什么。

SW

3 个答案:

答案 0 :(得分:2)

Doctrine的转换和验证的主要问题是它默认读取整个数据库和所有表,无论它们是否存在实体或映射。即使在调用--filter=""orm:convert:mapping

时使用orm:generate:entities标记也是如此

要解决此问题并让Doctrine跳过抛出异常的表,您可以将Doctrine设置为仅读取所需的表,方法是使用setFilterSchemaAssetsExpression

定义它们
$isDev = true;

$config = \Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration(array('/path/to/entities'), $isDev);
$config->setFilterSchemaAssetsExpression('/^(table1|table2|prefixed_.*|.*_suffixed)$/');

$em =  \Doctrine\ORM\EntityManager::create(array(
    'driver' => 'db_driver',
    'host' => 'localhost',
    'user' => 'user_name',
    'password' => 'user_password',
    'dbname' => 'database',
), $config);

或者您可以为现有实体管理器的连接设置过滤器。

$em->getConnection()->setFilterSchemaAssetsExpression('/^(filtered_table)$/');

参考: http://doctrine-orm.readthedocs.org/en/latest/reference/configuration.html

当然,这不是一种告诉学说忽略异常的方法,但应该帮助您开始学习某些特定​​表而不是整个数据库的现有应用程序。


作为附注,因为你提到你有链接表。 如果您在表中没有包含在过滤器中的外键,则--from-database转换仍将为其创建引用。 您必须手动将映射更改为原始表单,而不是与OneToMany,ManyToOne或ManyToMany的关联映射。

来自doctrine orm:convert:mapping --from-database annotation /path/to/entities

的注释映射
/**
 * @ORM\Entity
 * @ORM\Table(name="order")
 */
class Order
{
  /** 
   * @var \Customer
   * @ORM\ManyToOne(targetEntity="Customer")
   * @ORM\JoinColumns({
   *   @ORM\JoinColumn(name="customer", referencedColumnName="id", nullable=true)
   * })
   */
   private customer;
}

/**
 * @ORM\Entity
 * @ORM\Table(name="order")
 */
class Order
{
  /** 
   * @var integer
   * @ORM\Column(name="customer", type="integer", nullable=true)
   */
   private customer;
}

然后不要忘记使用doctrine orm:validate-schema来确保映射同步。

答案 1 :(得分:1)

前一段时间我遇到了同样的问题。完全按照相同的顺序。首先,我必须将枚举映射到字符串,然后它抱怨丢失的主键。

我很确定没有办法忽略这些例外情况。或者至少我无法在文档或在线中找到一个。 所以我所做的是为没有一个表的所有表添加一个主键。喜欢 alter table add temp_id int primary key not null auto_increment;

然后我从那里开始看看要保留哪些实体以及要删除哪些实体。 否则,您可以复制db并删除没有主键的表。 但是如果db有很多表,可能需要一段时间,你应该考虑制作一个程序

答案 2 :(得分:1)

再次重访同样的问题。我发现似乎有用的是通过bootstrap文件在cli配置中使用过滤:

// bootstrap.php
require_once("vendor/autoload.php");

use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

$site_root = realpath(__DIR__ . "/../");

$paths = [ $site_root . "/libraries/Doctrine/Entities" ];
$isDevMode = false;

// used when building entities from database using command line tool
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);

$filter_include = [
    'some_table_name',
    'another_table_name',
    '.*some_sub_portion.*',
    '^some_table_prefix_.*',
    '.*some_table_suffix$'
];
$include_reg = '/^(' . implode('|', $filter_include) . ').*$/';

$filter_exclude = [
    // tables with no primary key generate exceptions
    'some_table_name',
    'another_table_name',
    '.*some_sub_portion.*',
    '^some_table_prefix_.*',
    '.*some_table_suffix$'
];
$exclude_reg = '/^(?!(?:' . implode('|', $filter_exclude) . ')$).*$/';

// use include list
//$config->setFilterSchemaAssetsExpression($include_reg);
// use exclude list
$config->setFilterSchemaAssetsExpression($exclude_reg);

// the connection configuration
$dbParams = array(
    'driver'   => 'pdo_mysql',
    'user'     => 'myuser',
    'password' => 'mypassword',
    'dbname'   => 'mydatabase',
);

$entityManager = EntityManager::create($dbParams, $config);

$platform = $entityManager->getConnection()->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');