Reputation: 608
For some reasons, I need to have tables with TIMESTAMP
fields.
I created my own Timestamp Type (Doctrine\DBAL\Types\Type
), it works fine.
But when I try to update my database structure, I got this.
Command line
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 Query
If I execute the following query on the database, I works :
ALTER TABLE MY_TABLE CHANGE DATE_CREATION DATE_CREATION timestamp DEFAULT CURRENT_TIMESTAMP
ORM.YML
But when I try to change it in MyTable.orm.yml
, like this :
dateCreation:
type: timestamp
nullable: true
column: DATE_CREATION
options:
default: CURRENT_TIMESTAMP
The executed query is
ALTER TABLE MY_TABLE CHANGE DATE_CREATION DATE_CREATION timestamp DEFAULT 'CURRENT_TIMESTAMP'
And it fails.
How can I set a working default value, so my database's structure can be up to date ?
I already tried to set options: default
to 0
, NULL
, CURRENT_TIMESTAMP
, 00:00:01
...
PHP 5.3.3 MySQL 5.1.63
Here is the Timestamp Type
I think that convert*() aren't that well.
<?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;
}
}
Upvotes: 2
Views: 4976
Reputation: 611
Not sure if my answer still helps, but maybe it will help someone in the future. The way we did it is only thru mappings, no extra types (timestamp is allowed by Doctrine). There's the solution:
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
The column definition makes sure it will be created properly, and options
settings make sure that when you run doctrine:schema:validate
, you will see it is in sync (it is used for cross-checking the defaults with current definition).
Same, if you'd like to make those columns nullable, you have to change columnDefinition
and add nullable: false
.
Hope that helps!
Upvotes: 2
Reputation: 608
Here is the solution to have more than one timestamp field in the table.
You need to have your own Timestamp type defined and added in AppKernel.php :
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');
}
In your entity definition, 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
And in the entity MyEntity.php, have a prePersist :
public function doPrePersist()
{
$this->dateCreation = new \DateTime();
}
That's how I made it work :-) Thx all for your help !
Upvotes: 0
Reputation: 21
I tried that and it worked for me :
dateCreation:
type: datetime
version: true
column: DATE_CREATION
with
"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"
Upvotes: 2
Reputation: 21
You can try to remove the quote around CURRENT_TIMESTAMP. The sql query is executed well without the quotes .
ALTER TABLE MY_TABLE CHANGE DATE_CREATION DATE_CREATION timestamp [NULL|NOT NULL] DEFAULT CURRENT_TIMESTAMP
Upvotes: -2