Reputation: 18893
I'm trying to apply the following migration:
Schema::table('users', function (Blueprint $table) {
$table->timestamp('created_at')->useCurrent()->change();
});
But artisan
says:
[Doctrine\DBAL\DBALException]
Unknown column type "timestamp" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL
\Types\Type::addType(). You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap(). I
f this error occurs during database introspection then you might have forgot to register all database types for a
Doctrine Type. Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMapp
edDatabaseTypes(). If the type name is empty you might have a problem with the cache or forgot some mapping inform
ation.
When I try to install mmerian/doctrine-timestamp
(composer install mmerian/doctrine-timestamp
), composer
says:
[InvalidArgumentException]
Could not find package mmerian/doctrine-timestamp at any version for your minimum-stability (stable). Check the pa
ckage spelling or your minimum-stability
What do I do?
UPD With composer require mmerian/doctrine-timestamp=dev-master
, I was able to install the package, then added Type::addType('timestamp', 'DoctrineTimestamp\DBAL\Types\Timestamp');
before Schema::table
statement, but now I've got the other error:
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'created_at' (SQL: ALTER TABLE u
sers CHANGE created_at created_at INT DEFAULT 'CURRENT_TIMESTAMP' NOT NULL)
UPD I checked again if it works with mmerian/doctrine-timestamp
, since I added only first of the lines from the docs back then (or the doc was updated):
Type::addType('timestamp', 'DoctrineTimestamp\DBAL\Types\Timestamp');
DB::getDoctrineConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('Timestamp', 'timestamp');
But it doesn't help as well. The migration succeeds, but the column definition doesn't change.
Upvotes: 14
Views: 20100
Reputation: 536
To prevent adding Dbal using on app config I am using this in my migration class.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateSlidePropsonSlidesTable extends Migration
{
public function __construct()
{
// ! This is to allow changing timestamps without forcing require dbal on non dev composer.
\Doctrine\DBAL\Types\Type::addType(
'timestamp',
\Illuminate\Database\DBAL\TimestampType::class
);
}
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('slides', function (Blueprint $table) {
$table->renameColumn('date_start', 'publish_at');
$table->renameColumn('date_end', 'unpublish_at');
});
Schema::table('slides', function (Blueprint $table) {
$table->timestamp('publish_at')->nullable()
->change()
->comment('The date where the console published state should be changed to published.');
$table->timestamp('unpublish_at')->nullable()
->change()
->comment('The date where the console published state should be changed to archived.');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('slides', function (Blueprint $table) {
$table->renameColumn('publish_at', 'date_start');
$table->renameColumn('unpublish_at', 'date_end');
});
}
}
Upvotes: 0
Reputation: 14657
With the current Laravel version you just need to add the following to your config/database.php
and changing timestamp
columns in migrations will work.
use Illuminate\Database\DBAL\TimestampType;
'dbal' => [
'types' => [
'timestamp' => TimestampType::class,
],
],
Upvotes: 13
Reputation: 1522
if you want to make migration for current timestamp and get the error "Unknown column type "timestamp" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType()" then use like this
\DB::statement("ALTER TABLE `order_status_logs` CHANGE `created_at` `created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP");
Upvotes: 1
Reputation: 103
hi~ you can use "datetime" type:
Schema::table('orders', function ($table) {
$table->datetime('pay_time')->nullable()->change();
});
Upvotes: 7
Reputation: 664
I builded this for it, since Doctrine does not want to support it cause it's a MySQL-specific column type.
Upvotes: 0
Reputation: 18893
As one can see, mmerian/doctrine-timestamp
doesn't solve the issue. First, after this line $table->getColumns()['created_at']
is
class Doctrine\DBAL\Schema\Column#520 (16) {
protected $_type => class Doctrine\DBAL\Types\DateTimeType#504 (0) { }
protected $_length => NULL
protected $_precision => int(10)
protected $_scale => int(0)
protected $_unsigned => bool(false)
protected $_fixed => bool(false)
protected $_notnull => bool(true)
protected $_default => string(17) "CURRENT_TIMESTAMP"
protected $_autoincrement => bool(false)
protected $_platformOptions => array(0) { }
protected $_columnDefinition => NULL
protected $_comment => NULL
protected $_customSchemaOptions => array(0) { }
protected $_name => string(10) "created_at"
protected $_namespace => NULL
protected $_quoted => bool(false)
}
and $this->getTableWithColumnChanges($blueprint, $table)->getColumns()['created_at']
is
class Doctrine\DBAL\Schema\Column#533 (16) {
protected $_type => class DoctrineTimestamp\DBAL\Types\Timestamp#513 (0) { }
protected $_length => NULL
protected $_precision => int(10)
protected $_scale => int(0)
protected $_unsigned => bool(false)
protected $_fixed => bool(false)
protected $_notnull => bool(true)
protected $_default => string(17) "CURRENT_TIMESTAMP"
protected $_autoincrement => bool(false)
protected $_platformOptions => array(0) { }
protected $_columnDefinition => NULL
protected $_comment => NULL
protected $_customSchemaOptions => array(0) { }
protected $_name => string(10) "created_at"
protected $_namespace => NULL
protected $_quoted => bool(false)
}
So, first I can't see information about ON UPDATE
part here. Second, the onle difference is $_type
value. What I can confirm after this line, $tableDiff->changedColumns['created_at']->changedProperties
is
array(1) {
[0] => string(4) "type"
}
Then, when generating ALTER TABLE
statement, it all comes down to this
public function getDefaultValueDeclarationSQL($field)
{
$default = empty($field['notnull']) ? ' DEFAULT NULL' : '';
if (isset($field['default'])) {
$default = " DEFAULT '".$field['default']."'";
if (isset($field['type'])) {
if (in_array((string) $field['type'], array("Integer", "BigInt", "SmallInt"))) {
$default = " DEFAULT ".$field['default'];
} elseif (in_array((string) $field['type'], array('DateTime', 'DateTimeTz')) && $field['default'] == $this->getCurrentTimestampSQL()) {
$default = " DEFAULT ".$this->getCurrentTimestampSQL();
} elseif ((string) $field['type'] == 'Time' && $field['default'] == $this->getCurrentTimeSQL()) {
$default = " DEFAULT ".$this->getCurrentTimeSQL();
} elseif ((string) $field['type'] == 'Date' && $field['default'] == $this->getCurrentDateSQL()) {
$default = " DEFAULT ".$this->getCurrentDateSQL();
} elseif ((string) $field['type'] == 'Boolean') {
$default = " DEFAULT '" . $this->convertBooleans($field['default']) . "'";
}
}
}
return $default;
}
Somewhere around this line there supposed to be a check for Timestamp
type to turn 'CURRENT_TIMESTAMP'
into CURRENT_TIMESTAMP
. Is this possible within mmerian/doctrine-timestamp
? That question is left open for now. This check would most likely solve my particular issue. But for now I'm going to get away with this:
DB::statement('ALTER TABLE users MODIFY COLUMN created_at
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP');
Upvotes: 7
Reputation: 5332
Set minimum-stability
setting to dev
in your composer.json, because mmerian/doctrine-timestamp
has only dev-master
version, to example:
{
"minimum-stability": "dev",
"require": {
...
}
}
Then, when bootstraping your doctrine connection:
Type::addType('timestamp', 'DoctrineTimestamp\DBAL\Types\Timestamp');
$conn->getDatabasePlatform()->registerDoctrineTypeMapping('Timestamp', 'timestamp');
Upvotes: 0