jhartwell/Plsm

In MySQL, tinyint(1) boolean fields are not mapped

Closed this issue · 8 comments

  • Create a MySQL table with a bit field (e.g. rails boolean)
  • Run plsm
  • The bit field will be omitted

MySQL 5.6
PLSM 1.1.2
Mix/Elixir 1.4.2

@richdrich TINYINT(1) cannot be mapped to a boolean field as it can have a value between 0 and 9. A TINYINT can be between -128 and 127 (according to https://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html). TINYINT(1) will take the first digit of of the TINYINT, which .means it can be more than just 0 or 1. A Bit column can also be more than just one or zero and contain extra values (such as an Enum). Because of that, I'm not going to make them map to boolean. That said, I will add them as integers so that they will appear and then you can manually change them.

@richdrich this has been added in version 1.1.3. Please update to that version in your mix.exs dependencies.

@richdrich - I have just released version 2.0.0, please use that version instead of 1.1.3 as it contains other changes. Thanks!

Thanks for this and for making a great module!

My use case, BTW, is importing the schema for a fairly complex Rails database into Elixir so our microservice can see the application data. I've managed to do this with a bit of manual tweaking (the generated cast statement needed to change, but possibly this was my Elixir setup, so I haven't logged an issue on that yet).

What would be really nice would be a facility to configure the SQL type/Ecto type mappings to compensate for the data loss. [Or I could take another approach and transpile Active Record schemas into Ecto].

@richdrich Thanks for the use case. What do you mean by compensating for the data loss? Do you mean fields getting trimmed (e.g varchar(255) to varchar(200)?

Ah, no. I was thinking that Rails sees a field as e.g:

 t.boolean  "is_deferred_income",  default: false

while in MySQL it's just:

is_deferred_income` tinyint(1) DEFAULT '0'

The boolean typedness gets lost (as you note above). But with our Rails system, we know that a tinyint(1) is always used to code a boolean and never an integer, so if I could configure:
{ 'tinyint(1)', 'boolean' } then that would let me generate model files that wouldn't need to be altered by hand?

@richdrich, alright, that makes sense. I'm a SQL Server guy so I'm used to using a bit as a boolean for database, what is the "standard" for boolean in MySQL? Is it tinyint(1) with a default value? Just tinyint(1)? I don't mind adding a flag on to do this but it definitely wouldn't be standard behavior.

Merged into develop branch