【问题标题】:Doctrine2 - Type timestamp - Default valueDoctrine2 - 类型时间戳 - 默认值
【发布时间】:2015-05-05 14:14:05
【问题描述】:

由于某些原因,我需要有带有TIMESTAMP 字段的表。

我创建了自己的时间戳类型 (Doctrine\DBAL\Types\Type),它工作正常。

但是当我尝试更新我的数据库结构时,我得到了这个。

命令行

ede80:~>php app/console doctrine:schema:update --force --complete
Updating database schema...

  [Doctrine\DBAL\Exception\DriverException]
  An exception occurred while executing 'ALTER TABLE MY_TABLE CHANGE DATE_CREATION DATE_CREATION timestamp DEFAULT NULL'

  SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'DATE_CREATION'

SQL 查询

如果我在数据库上执行以下查询,我可以工作:

ALTER TABLE MY_TABLE CHANGE DATE_CREATION DATE_CREATION timestamp DEFAULT CURRENT_TIMESTAMP

ORM.YML

但是当我尝试在MyTable.orm.yml 中更改它时,像这样:

    dateCreation:
        type: timestamp
        nullable: true
        column: DATE_CREATION
        options:
            default: CURRENT_TIMESTAMP

执行的查询是

ALTER TABLE MY_TABLE CHANGE DATE_CREATION DATE_CREATION timestamp DEFAULT 'CURRENT_TIMESTAMP'

它失败了。

如何设置一个有效的默认值,以便我的数据库结构可以是最新的? 我已经尝试将options: default 设置为0NULLCURRENT_TIMESTAMP00:00:01...

PHP 5.3.3 MySQL 5.1.63

这是时间戳类型

我认为 convert*() 不太好。

<?php
namespace CNAMTS\PHPK\CoreBundle\Doctrine\Type;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

/**
 */
class Timestamp extends Type
{
    const TIMESTAMP = 'timestamp';

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return $platform->getDoctrineTypeMapping('TIMESTAMP');
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return ($value === null) ? 0 : new \DateTime($value);
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return ($value === null) ? 0 : $value->format(\DateTime::W3C);
    }

    public function getName()
    {
        return self::TIMESTAMP;
    }
}

【问题讨论】:

  • 为什么不想使用 DATETIME 类型? stackoverflow.com/questions/409286/datetime-vs-timestamp
  • 我已经阅读了这个页面,但是我不能,不幸的是,这是我工作的标准。我知道,这很愚蠢。
  • 您可以尝试将您的属性定义为 Doctrine 的 datetime 类型,也许它会起作用,因为 datetime 在 PostgreSQL 中被解释为 TIMESTAMP
  • 感谢您的提示,我有效地尝试过,但它们存储为 Datetime 字段,我需要 Timestamp 字段。我实际上使用 MySQL。

标签: php mysql symfony doctrine-orm timestamp


【解决方案1】:

我试过了,它对我有用:

dateCreation:
        type: datetime
        version: true
        column: DATE_CREATION

    "doctrine/orm": "~2.2,>=2.2.3",
    "doctrine/doctrine-bundle": "~1.2",
    "doctrine/doctrine-fixtures-bundle": "~2.2"
    "doctrine/migrations": "dev-master",
    "doctrine/doctrine-migrations-bundle": "dev-master"

【讨论】:

  • 感谢您的提示,我不知道。它可以在我的情况下工作,但我至少需要 2 个 TIMESTAMP 字段,不幸的是,由于某些 DBMS 原因,这是不可能的(我使用 MySQL 5.1.63,此限制已在 MySQL 5.6.5 中删除)。所以我会保留我的第一个解决方法:-/ 但不错的尝试!
【解决方案2】:

不确定我的回答是否仍然有帮助,但也许将来会对某人有所帮助。我们这样做的方式只是通过映射,没有额外的类型(Doctrine 允许时间戳)。有解决办法:

dateAdd:
     type: datetime
     column: date_add
     columnDefinition: TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
     options:
         default: CURRENT_TIMESTAMP
editDate:
     type: datetime
     column: date_edit
     columnDefinition: TIMESTAMP on update CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
     options:
         default: CURRENT_TIMESTAMP

列定义确保它被正确创建,options 设置确保当你运行doctrine:schema:validate 时,你会看到它是同步的(它用于交叉检查当前定义的默认值) .

同样,如果您想让这些列可以为空,您必须更改 columnDefinition 并添加 nullable: false

希望有帮助!

【讨论】:

  • 我对这个解决方案有疑问。 Doctrine 尝试在插入/更新时将“null”保存到日期字段。
【解决方案3】:

这是在表中有多个时间戳字段的解决方案。

您需要在 AppKernel.php 中定义并添加自己的 Timestamp 类型:

public function boot() {
    parent::boot();

    /**
     * SQL type TIMESTAMP
     */
    $em = $this->container->get('doctrine.orm.default_entity_manager');
    Doctrine\DBAL\Types\Type::addType('timestamp', 'My\CoreBundle\Doctrine\Type\Timestamp');
    $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('TIMESTAMP', 'timestamp');
}

在您的实体定义中,MyEntity.orm.yml

 dateCreation:
        type: timestamp
        nullable: false
        column: DATE_CREATION
        columnDefinition: TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00'
    dateModification:
        type: timestamp
        nullable: false
        column: DATE_MODIFICATION
        columnDefinition: TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

并且在实体MyEntity.php中,有一个prePersist:

public function doPrePersist()
{
    $this->dateCreation = new \DateTime();
}

这就是我让它工作的方式:-) 谢谢大家的帮助!

【讨论】:

    【解决方案4】:

    您可以尝试删除 CURRENT_TIMESTAMP 附近的报价。没有引号的sql查询执行得很好。

    ALTER TABLE MY_TABLE CHANGE DATE_CREATION DATE_CREATION timestamp [NULL|NOT NULL] DEFAULT CURRENT_TIMESTAMP
    

    【讨论】:

    • 怎么样?我自己不执行查询,我让 Doctrine 处理它。
    • 你能发布你的时间戳类型吗?
    • 如果你使用symfony,你为什么不这样声明你的TIMESTAMP?字段:myDate:类型:日期时间版本:true
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多