Skip to content

Instantly share code, notes, and snippets.

@zymsys
Last active November 5, 2015 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zymsys/9581bd7ad50845acfebe to your computer and use it in GitHub Desktop.
Save zymsys/9581bd7ad50845acfebe to your computer and use it in GitHub Desktop.
DBAL & MySQL JSON

When I have a table in a database which has a json column I can't use doctrine:schema:update --force because I get this error:

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

Break on exception shows this happening at \Doctrine\DBAL\Platforms\AbstractPlatform\getDoctrineTypeMapping because 'json' can't be found in $this->doctrineTypeMapping. This is initialized by the abstract function initializeDoctrineTypeMappings which in this case is implemented in \Doctrine\DBAL\Platforms\MySqlPlatform. Sure enough there is no 'json' key.

It looks like the array keys are native column types, and the array values are DBAL column types.

I know that mysql has a 'json' column type, and I know that DBAL has a 'json_array' column type. Let's take a shot in the dark...

Ok, that got rid of the error message. Not sure if I did any damage.

Entities that I've declared with 'json_array' types are still mapped to longtext though. It'd be nice if they mapped to json. A few more minutes in the debugger and I've got this tracked down to \Doctrine\DBAL\Platforms\AbstractPlatform\getJsonTypeDeclarationSQL. This relayed to getClobTypeDeclarationSQL (CLOB = Character Large Object).

This is actually an instance of MySQL57Platform, so I should override this there instead of changing the default behavour. Except that the json column type was added in MySQL 5.7.8. So, more accurately I should create a new MySQL578Platform class and override it there.

The platform is detected by \Doctrine\DBAL\Driver\AbstractMySqlDriver\createDatabasePlatformForVersion. Easily modified to load my own MySQL578Platform class which overrides getJsonTypeDeclarationSQL to return 'json'. And it runs. I now have it generating a table with real json columns. Woo hoo!

Now, do they actually work...

  • Create? Check.
  • Report? Bzzt. Warning: PDOStatement::execute(): Unknown type 245 sent by the server. Please send a report to the developers
  • Update? Not without report.
  • Delete? Not without report.

So - I need json support in mysql. A little digging later, and it looks like pdo_mysql gets this either from mysql drivers available when PHP is compiled, or from the built-in mysqlnd drivers. A quick grep of the latest mysqlnd source indicates support for json. When was this added? PHP 5.6.16. Supported by brew. Sweet. Upgrade complete.

  • Create? Check.
  • Report? Check.
  • Update? Check.
  • Delete? Check.

Good enough for basic JSON support and Doctrine hand in hand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment