-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQLite3 doesn't actually support the 'time' type. #6344
Conversation
SQLite3 doesn't actually support the 'time' type.
I'm not sure that this was a good idea. Now you can't use I'm not 100% sure what we should do about the situation. If this example wasn't using string substitution, we could detect the column type as |
Isn't it best to use the same database in testing and production? |
I should say same database type. There are a number of differences between SQLite and Postgres. It seems like a bad idea to test in a different database type. Plus it seems like it would add extra complexity automatically using SQLite functions. But I don't have the experience you have, if you think we should do it a different way I'd be happy to work on another approach with you. It would be a good opportunity for me to get my hands dirty going a bit deeper into ActiveRecord. |
Well, this is related to #6825 and pull request #6835. @mauricio do you have any ideas how we could handle this? We use SQLite3 in dev and Oracle in production (setting up Oracle is too hard). That said, we don't have any time only columns at work. @erichmenge I'm not sure if I have a better approach. TBH, it seems like if we can't truly support OTOH, we could just say "this is a place where we can't make databases behave the same" and skip tests in sqlite3 on #6835. @erichmenge thoughts? |
@tenderlove I'm +1 for not failing silently as it is today. Letting someone use a Imagine a form generator that checks the columns and their types, I did define this field to be a If you are using SQLite you should probably be aware of this interesting behavior of your database and you should be able to work around it yourself (not being able to cleanly handle dates and times in general). We can even add this information cleanly at the AR documentation so everyone is aware that while you can define a I think throwing an exception might be too harsh, specially for people like @tenderlove that use SQLite in development and something else in production (which is pretty common, I have done this myself and my target was MS SQL Server), as they would have to work some magic to get Other databases will handle his case correctly (MySQL and PostgreSQL do have time fields and will just work). |
Sorry for not thinking about this more thoroughly before merging. I would do 2 things:
I would not raise, as @mauricio says, because people might still want to use this if the know that it needs workaround. |
There's no problem with using the When a time columns is read from the database it has it's date changed to 1/1/2000 by Rails, but it's not changed when when the value is written (we should do to fix #3145). Whether by design or luck this is the date that Sqlite assumes when given a time string of 'HH:MM:SS' so we should probably send that instead. The problem is how to handle querying - we can cast to a time string when using So we need to revert this commit and address how we are sending time strings to the database. |
Just to clarify |
This commit needs to be reverted because it introduces difficulties when using sqlite3 in development and other databases in production. This happens because when you create time column in sqlite3, it's dumped as datetime in schema.rb file. This reverts commit 57d534e, reversing changes made to 20f049f. Conflicts: activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
I've reverted the commit, because it seems that it's the best thing we can do, regardless sqlite3 behavior is fixed or not. |
When I originally made the PR it occurred to me that we could make the necessary SQLite function calls to support Time. As @tenderlove points out in #6835 it is already done for other column types in SQLite. But it seemed to me that it would be a complicated endeavor as Time related things can be. @pixeltrix Would it be better to build this functionality into Rails or issue a warning and allow the developer to make the necessary adjustments to queries to use the SQLite date/time functions? If you want to bake this support into Rails I'd be happy to help, though I may need a bit of guidance. |
IMO, we should just emit a warning during migrations or add some documentation (or both). There's no way we'll be able to "do the right thing" when someone issues a query like |
Or: whoever codes this feature is responsible for fixing all of the related bug reports |
Okay, it sounds like the warning is the way to go. I'll get that taken care of and submit a new PR. Thanks for the feedback everyone, sorry I missed the schema discrepancy consideration on the original PR. |
We can't issue a warning when someone does a I did toy with the idea of creating a new class to represent a time only but I guess this is something we wouldn't want to do - I can't even think of a good class name :-) |
I think the warning is mostly for the @pixeltrix LocalTime maybe? Having a class for this would be nice, a very simple implementation would just have the same methods |
Since warnings are silenced for rake tasks, should this warning be emitted only for the logger? Or should the warning be issued to stderr anyway? I feel like the messages might be a bit noisy with no way to turn them off. On the other hand if they are issued to the logger only, who will see them? |
Relates to #6247.
SQLite3 does not support the 'time' data type. I feel like we shouldn't pretend it does.
As it is now, if you create a new record with time only, the year gets set as the current year in the database. However, as in issue #6247 when you do
Alert.all
it shows the year as being 2000. Subsequently you get this behavior:It isn't very consistent to show
start: "2000-01-01"
and yet not find it. The reason is it really has year 2012 in the database.I realize the year is just a dummy year since Ruby doesn't support any concept of time only. But the difference is MySQL and PostgreSQL don't actually store the year in the database, where as SQLite does, and it doesn't match what Rails displays.
As an aside, I had to add:
to a couple of the tests, because when I changed line 955 to skip SQLite3 adapter, those lines getting skipped at the end were causing those other two tests to fail. I don't see any tests that set those attributes and not set them back, but I guess something funny is going on there.