Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mehany's avatar
Level 13

Doctrine\DBAL: How to add data types when using Xethron/migrations-generator

Hello,

I would like to add data types such as postgres geometry when using Doctrine\DBAL\Platforms\PostgreSqlPlatform to generate migrations of an existing database. I am not sure where to place the mapping of data types! Hope someone here can help!

I currently get the following error:

[Doctrine\DBAL\DBALException]                                                                             
  Unknown database type geometry requested, Doctrine\DBAL\Platforms\PostgreSqlPlatform may not support it. 

Not sure yet how to follow the docs for custom-mapping-types within Laravel!

0 likes
6 replies
mehany's avatar
Level 13

@marciocar I wish someone more experienced to answer this! what I did does not answer my question the right way! Given that I had a lot of tables, I really needed to get this going, so I end up modifying the vendor file itself right here. I needed to just reverse-generate the modules's attributes for those tables and that served my purpose.

1 like
marciocar's avatar

Hi @mehany,

Very thanks,

Your tip was crucial for the solution this problem.

I added GeometryType.php, created by Rauni Lillemets, in vendor\doctrine\dbal\lib\Doctrine\DBAL\Types

I added the geometry type on array doctrineTypeMapping in vendor\doctrine\dbal\lib\Doctrine\DBAL\Platforms\PostgreSqlPlatform.php

   protected function initializeDoctrineTypeMappings()
    {
        $this->doctrineTypeMapping = array(
            ...
            'geometry'  => 'geometry',
        );
    }
    

I altered the file Type.php in vendor\doctrine\dbal\lib\Doctrine\DBAL\Types

Add the constant

const GEOMETRY = 'geometry';

I chanded the const GEOMETRY in array _typesMap

private static $_typesMap = array(
    ...
    self::GEOMETRY => 'Doctrine\DBAL\Types\GeometryType',
);

Run command

php artisan migrate:generate

The result on my migration generated

public function up()
{
    Schema::create('private_area', function(Blueprint $table)
    {
        $table->integer('id', true);
        $table->string('name')->nullable();
        $table->geometry('geom')->nullable()->index('idx_private_area_geom');
    });
}   

Very very thanks @mehany,

GeometryType.php


namespace Doctrine\DBAL\Types;

use Doctrine\DBAL\Platforms\AbstractPlatform;

/**
 * Class for database column "geometry".
 *
 * @author Rauni Lillemets
 */
class GeometryType extends Type {
    const GEOMETRY = 'geometry';
    const SRID = 3301;
    public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) {
        return 'geometry';
    }
//Should create WKT object from WKT string. (or leave as WKT string)
    public function convertToPHPValue($value, AbstractPlatform $platform) {
        return $value; //+
    }
//Should create WKT string from WKT object. (or leave as WKT string)
    public function convertToDatabaseValue($value, AbstractPlatform $platform) {
        return $value; //+
    }
    public function getName() {
        return self::GEOMETRY;
    }
    public function canRequireSQLConversion() {
        return true;
    }
//Should give WKT
    public function convertToPHPValueSQL($sqlExpr, $platform) {
        return 'ST_AsText(\''.$sqlExpr.'\') '; //+
    }
//Should create WKB
    public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) {
        return 'ST_GeomFromText(\''.$sqlExpr.'\', '.self::SRID.')'; //+
    }
}


1 like
mehany's avatar
mehany
OP
Best Answer
Level 13

@marciocar great work putting this together here, I selected your answer as the correct answer because there is a pull request to solve this on DBAL package which should actually contain Geometry data type mapping.

P.S

Pull request was not accepted because:

this type isn't portable across different vendors and thus cannot be added to the core.

So as of now, the type should be written some where then registered like this

     <?php
// in bootstrapping code

// ...

use Doctrine\DBAL\Types\Type;

// ...

// Register my type
Type::addType('mytype', 'My\Project\Types\MyType');

To convert the underlying database type of your new “mytype” directly into an instance of MyType when performing schema operations, the type has to be registered with the database platform as well - I will look into this and refer to https://laracasts.com/discuss/channels/laravel/adding-custom-dbal-to-laravel-5 answer to his own question and update this thread :

<?php
$conn = $em->getConnection();
$conn->getDatabasePlatform()->registerDoctrineTypeMapping('db_mytype', 'mytype');

http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html

rgoodyear's avatar

@mehany where is "some where" in bootstrapping code? And where does the second code snippet go?

Please or to participate in this conversation.