我第一次坐下了学说并试图在现有的网站/数据库上使用它的一些命令行工具。我从命令行使用了映射和实体逆向工程工具,想看看它将从php / mysql中的现有网站生成什么类型的文件。
但是,它会在任何例外情况下停止。我已经能够为枚举创建一个类型映射,现在就将它们抛出一个字符串,但是现在它阻止了我没有指定主ID密钥的表。我对在链接表中使用主键或复合键的演讲不感兴趣,我只是在学习Doctrine时尝试生成一些输出。
有没有一种方法可以告诉学说跳过抛出异常的表,或者在它们击中它时不停止的情况下通过?我现在只想要一些示例输出,并且不想完全重新考虑复杂的数据库因为看看Doctrine可以做什么。
SW
答案 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');