RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 670494
Accepted
mxSandr
mxSandr
Asked:2020-05-25 12:30:00 +0000 UTC2020-05-25 12:30:00 +0000 UTC 2020-05-25 12:30:00 +0000 UTC

Doctrine:doctrine 如何跟踪@Column 映射中的表名更改

  • 772

有一个类,数据库中已经有一些数据:

class Me
{
    /**
     * @Column(name="field",type="string")
     */
    $field;

    /**
     * @Column(name="fieldTwo",type="int")
     */
    $fieldTwo;
}

我更改映射中第一个字段的列的名称:field --> some_field

class Me
{
    /**
     * @Column(name="some_field",type="string")
     */
    $field;

    /**
     * @Column(name="fieldTwo",type="int")
     */
    $fieldTwo;
}

发射

doctrine:schema:update

我希望 Doctrine 忘记旧的字段列并创建一个新的 some_field。但是该学说以某种方式理解有必要重命名现有列,而不是忘记旧列并创建一个新列。这不符合我的想法。有没有人遇到过这种行为,是什么原因造成的,如何管理?

PS 我注意到该学说没有在项目文件中创建任何关于映射的数据,开发是代码优先的。

symfony3
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Вадим Бондаренко
    2020-05-25T18:10:54Z2020-05-25T18:10:54Z

    您对类属性进行了剖析。属性不变,注释更新,因此学说更新名称。

    Doctrina 查看实体类并将其与当前版本的数据库进行比较,发现差异并作为结果对其进行更新。

    顺便说一句,Symfony 有一个 DoctrineMigrationsBundle 包,它允许你存储数据库版本状态。但这是另一个话题,与问题无关。

    • 1
  2. Best Answer
    mxSandr
    2020-05-26T21:02:06Z2020-05-26T21:02:06Z

    事实证明,一切都是合法的。在:

    doctine:scheme:update
    

    调用类方法 Doctrine\DBAL\Schema\Comparator compare(),其中顺序比较所有表的变化:

    foreach ($toSchema->getTables() as $table) {
            $tableName = $table->getShortestName($toSchema->getName());
            if ( ! $fromSchema->hasTable($tableName)) {
                $diff->newTables[$tableName] = $toSchema->getTable($tableName);
            } else {
                $tableDifferences = $this->diffTable($fromSchema->getTable($tableName), $toSchema->getTable($tableName));
                if ($tableDifferences !== false) {
                    $diff->changedTables[$tableName] = $tableDifferences;
                }
            }
        }
    

    让我们看看diffTable()代码:

    foreach ($table2Columns as $columnName => $column) {
        if ( !$table1->hasColumn($columnName)) {
            $tableDifferences->addedColumns[$columnName] = $column;
            $changes++;
        }
    }
    /* See if there are any removed fields in table 2 */
    foreach ($table1Columns as $columnName => $column) {
        // See if column is removed in table 2.
        if ( ! $table2->hasColumn($columnName)) {
            $tableDifferences->removedColumns[$columnName] = $column;
            $changes++;
            continue;
        }
    

    正如我所料,该学说列出了目前不在数据库中的那些列,以及新映射中存在但不在数据库中的列的列表。但进一步在 diffTable 中,之后调用了detectColumnRenamings()方法,其中发生了所有魔术:

     this->detectColumnRenamings($tableDifferences);
    

    他的代码:

    private function detectColumnRenamings(TableDiff $tableDifferences)
    {
        $renameCandidates = array();
        foreach ($tableDifferences->addedColumns as $addedColumnName => $addedColumn) {
            foreach ($tableDifferences->removedColumns as $removedColumn) {
                if (count($this->diffColumn($addedColumn, $removedColumn)) == 0) {
                    $renameCandidates[$addedColumn->getName()][] = array($removedColumn, $addedColumn, $addedColumnName);
                }
            }
        }
    
        foreach ($renameCandidates as $candidateColumns) {
            if (count($candidateColumns) == 1) {
                list($removedColumn, $addedColumn) = $candidateColumns[0];
                $removedColumnName = strtolower($removedColumn->getName());
                $addedColumnName = strtolower($addedColumn->getName());
    
                if ( ! isset($tableDifferences->renamedColumns[$removedColumnName])) {
                    $tableDifferences->renamedColumns[$removedColumnName] = $addedColumn;
                    unset($tableDifferences->addedColumns[$addedColumnName]);
                    unset($tableDifferences->removedColumns[$removedColumnName]);
                }
            }
        }
    }
    

    如果您阅读了该方法的代码(最好是对它的注释 :)),并且还看到了diffColumn()方法的作用(返回对两个任意列的更改),那么很明显:

    • 如果新映射和现有数据库中有一个相同的字段(类型、长度等,对完整的条件列表感兴趣,欢迎使用diffColumn()方法),那么该列将被重命名。
    • 如果一侧有多个这样的列(旧映射和新映射),则该学说将创建一个新的空列,而保留旧列。
    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5