Doctrine 2: Resolving “unknown database type enum requested”

I came across this recently while I was developing a module for PyroCMS. Some of the PyroCMS tables contain ENUM columns, which Doctrine doesn’t support. You would think that this wouldn’t be an issue since these tables are not mapped, but apparently when Doctrine builds the schema it includes all tables in the database – even if they are not mapped. This has been reported as an issue, but the Doctrine team has given it a low priority.

The symptom? When using the SchemaTool to create, update, or drop the schema; an exception is thrown:

Fatal error: Uncaught exception 'Doctrine\DBAL\DBALException' with message 'Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.'

Thankfully, the fix is very easy. There is even a Doctrine Cookbook article about it. All you have to do is register the ENUM type as a Doctrine varchar (string):

/** @var $em \Doctrine\ORM\EntityManager */
$platform = $em->getConnection()->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');

This fix can be applied to any unsupported data type, for example SET (which is also used in PyroCMS):

$platform->registerDoctrineTypeMapping('set', 'string');

Did you find this post useful?

  • Albert R. Carnier Guedes

    I put this on bootstrap.php

    $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping(‘enum’, ‘string’);

    And solve to me.

  • alsbury

    Thanks, very handy

  • Eran Or

    as usual, frustration will not break me.
    (don’t copy from here the first part but just the second because you will need the spaces/
    copy from:
    http://symfony.com/doc/master/reference/configuration/doctrine.html#reference-dbal-configuration
    )
    if some body want the full solution:

    #add the following to app/config/config.yml
    doctrine:
    dbal:
    driver: %database_driver%
    host: %database_host%
    port: %database_port%
    dbname: %database_name%
    user: %database_user%
    password: %database_password%
    charset: UTF8
    mapping_types:
    enum: string

    #add the following to your Somefile.orm.yml
    gender:
    type: string
    columnDefinition: ENUM(‘male’,’female’)

  • http://twitter.com/remyfrd Rémy
  • http://gravatar.com/umpirsky umpirsky

    Where should I place this code?

    • http://wildlyinaccurate.com/ Joseph

      You can put this code anywhere, but it’s probably best if you place it in your Doctrine bootstrap/loader.

  • MR

    It is absurd that Doctrine doesn’t support ENUM out of the box. MySQL is by far the most popular database for PHP projects, and ENUM is very useful. Doctrine project managers are putting principle ahead of pragmatism, and most users suffer because of it.

  • Rex

    Hi,

    After several hours of trying everything and raging, I can’t seem to get this to work. Wherever I put this code, it does not execute, as if it cannot find the Entity Manager $em, even when I try to create it with $em = $this->get(‘doctrine’)->getEntityManager();. I normally just keep trying and googling but I’m about to throw my laptop through the window, so to save it I figured it’d be better to just ask for help.

    Could you tell me one specific place in Symfony where you are sure this code would work? Or am I forgetting something trivial?

    • http://wildlyinaccurate.com/ Joseph

      Hi Rex,

      Are you using Symfony2? In a Symfony2 controller you would do $em = $this->getDoctrine()->getEntityManager(); or $em = $this->container->get('doctrine')->getEntityManage();

      My Symfony is a bit rusty so I’m not sure how helpful that is…

      • Rex

        Thank you, that actually worked. I had tried putting some PHP in the controller first, but I failed to actually get the Entity Manager. Again, thank you, you’re a great help. :)

        • http://twitter.com/nochnPirat rot-13(XNV OENRAQYR)

          Its an old Entry, but this blog is the first Googleresult when searching for this Problem. So for other Symfony2 beginners i like to share an easy solution. You just have to modify your config.yml so it reads in the doctrine part:

          # Doctrine Configuration

          doctrine:

          charset: UTF8
          mapping_types:
          enum: string

          orm:

          Thats it.

      • Rex

        Just kidding. The PHP seems to be parsed but upon running
        sudo php app/console doctrine:mapping:convert xml ./src/MyProject/MyBundle/Resources/config/doctrine/metadata/orm --from-database --force
        it still gives me the following error:
        [Doctrine\DBAL\DBALException]
        Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.

        doctrine:mapping:convert [--filter="..."] [--force] [--from-database] [--extend[="..."]] [--num-spaces[="..."]] [--namespace[="..."]] [--em[="..."]] to-type dest-path

        Symfony’s dev.log error log gives me this:
        [2012-02-19 12:48:47] doctrine.DEBUG: SET NAMES UTF8 ([]) [] []
        [2012-02-19 12:48:47] doctrine.DEBUG: SHOW FULL TABLES WHERE Table_type = 'BASE TABLE' ([]) [] []
        [2012-02-19 12:48:47] doctrine.DEBUG: SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS CollactionName FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'project' AND TABLE_NAME = 'admins' ([]) [] []

        And MainController.php is getDoctrine()->getEntityManager();
        $platform = $em->getConnection()->getDatabasePlatform();
        $platform->registerDoctrineTypeMapping('enum', 'string');
        return $this->render('MyProjectMyBundle:Main:index.html.twig');
        }
        }
        ?>

        Upon calling app.php I get the correct page (which is rendered using index.html.twig) so I think I can safely assume it processes the PHP. However, for some reason every time I try to map the database with doctrine, it just keeps giving me the same error. Would you have any advice regarding this issue?

        Thanks in advance!
        Rex

        • Rex

          Apparently my pasted code for MainController.php didn’t get through properly, so here it is again.

          getDoctrine()->getEntityManager();
          $platform = $em->getConnection()->getDatabasePlatform();
          $platform->registerDoctrineTypeMapping('enum', 'string');
          return $this->render('WOWspotsCMSBundle:Main:index.html.twig');
          }
          }
          ?>

        • Rex

          I fixed it. What did the trick was changing the file MyProjectMyBundle.php to the following:


          container->get('doctrine')->getEntityManager();
          $platform = $em->getConnection()->getDatabasePlatform();
          $platform->registerDoctrineTypeMapping('enum', 'string');
          }
          }

          Thanks for all your help and hopefully others who have the same problem will read this. ;)

          • Rex

            Sigh. The code section doesn’t like the variable $this. For other readers, just add the following function to the class in MyProjectMyBundle.php:


            public function boot()
            {
            $em = (dollarsign)this->container->get('doctrine')->getEntityManager();
            $platform = $em->getConnection()->getDatabasePlatform();
            $platform->registerDoctrineTypeMapping('enum', 'string');
            }

          • http://wildlyinaccurate.com/ Joseph

            Thanks for sharing this experience, Rex. Just to confirm – to implement this in Symfony, you need to register the type mappings in the boot() function of your Bundle?

  • bizaflare

    Hi, Enums with CI2 and D2 still driving me nuts:
    I was using your tutorial with integrating these two and now I am at the point where I have to use enums – and was happy to see you having this issue adressed as well.

    However, I have tried several things now and I am confused on what I tried in which combination.
    Where (which file) do u specify these three lines of code to register the ENUM type as a Doctrine varchar (string)?

    Thanks!

    • http://wildlyinaccurate.com/ Joseph

      Hi, you can put this code anywhere but since you are using CodeIgniter I would recommend putting it in your Doctrine bootstrap file (application/libraries/Doctrine.php).

      • bizaflare

        I tried to paste this code below the create Entity Manager Command in the constructor of your Doctrine.php. But I’m getting “Fatal error: Call to undefined method Doctrine\ORM\EntityManager::registerDoctrineTypeMapping()”. I even tried to change it a bit into: $this->em->getConnection()->getDatabasePlatform();
        $this->em->registerDoctrineTypeMapping(‘enum’, ‘string’);
        with same result.

        Well, I think I got it working now by adding the third line in the contructor of the Schema Tool (/application/libraries/Doctrine/ORM/Internal/Tools/SchemaTool.php). However, this feels like a bad solution since I have to edit Doctrine’s core files :/

        • http://wildlyinaccurate.com/ Joseph

          Judging by your first error message, you’re calling $this->em->registerDoctrineTypeMapping(‘enum’, ‘string’) – it should be

          $platform = $this->em->getConnection()->getDatabasePlatform();
          $platform->registerDoctrineTypeMapping(‘enum’, ‘string’);
          

          I think you’re right about modifying the core files; it makes updating difficult.

          • bizaflare

            Thanks! Works like a breeze, now :)