Comments (31)
I ran into this issue a couple of days back - a quick workaround is to explicitly create a %Postgrex.Timestamp
struct and pass that.
That said, I've added a test that explicitly hits this issue (b9c5ea1) and I'm hoping to fix it when I get a chance.
from moebius.
I just pushed 2.0.2 which @nurugger07 fixed RE dates etc. Out of curiosity - did you try :now
?
from moebius.
Thanks :)
I just updated by doing mix deps.update moebius
and recompiled and I still get the same
** (FunctionClauseError) no function clause matching in Moebius.Extensions.DateExtension.encode/4
(moebius) lib/moebius/extensions/date_extension.ex:27: Moebius.Extensions.DateExtension.encode(%Postgrex.TypeInfo{array_elem: 0, base_type: 0, comp_elems: [], input: "date_in", oid: 1082, output: "date_out", receive: "date_recv", send: "date_send", type: "date"}, "2016-07-21", 6856750, nil)
(postgrex) lib/postgrex/query.ex:100: DBConnection.Query.Postgrex.Query.do_encode/4
(postgrex) lib/postgrex/query.ex:61: DBConnection.Query.Postgrex.Query.encode/3
(db_connection) lib/db_connection.ex:885: DBConnection.describe_execute/5
(db_connection) lib/db_connection.ex:1009: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:957: DBConnection.run_meter/3
(db_connection) lib/db_connection.ex:421: DBConnection.query/4
(postgrex) lib/postgrex.ex:111: Postgrex.query/4
I'm not sure what you mean by :now
? The original date string is coming from a JSON response.
from moebius.
Just to be sure: you updated the version in mix.exs right?
from moebius.
It would also be helpful if you described the problem a bit more. You can send in a Timex date and it will work. It's sort of hard to know what you're doing from the code here.
from moebius.
Just to be sure: you updated the version in mix.exs right?
I didn't as it was set like {:moebius, "~> 2.0.0"}
which should get me 2.0.2 right? Either way, I just change it to 2.0.2 and the same problem.
It would also be helpful if you described the problem a bit more. You can send in a Timex date and it will work. It's sort of hard to know what you're doing from the code here.
Sure. This could totally be user error as this is my first Elixir code :) format_date
returns a date string like "2017-01-01"
and I want to update the release_date
column with that. Do I need to pass a Timex date rather than a string?
from moebius.
Ahh! Yes don't bother with the string - just send in the Timex date. If you want to update it to now, just send in :now
:
def update_movie(release_date, movie) do
db(:movies)
|> filter(original_title: movie.original_title)
|> update(release_date: :now)
|> LetterboxdCal.Db.run
end
from moebius.
Ah, great. I just tried it with the Timex date directly. It doesn't work. I think the problem is that Timex.parse(date_string, "%Y-%m-%dT00:00:00.000Z", :strftime)
returns a DateTime
struct. I think I need convert it to a Date
somehow as the column in the database is date only?
from moebius.
One note: if you changed it to {:moebius, "~> 2.0"}
it will grab the
latest 2.0.* release :)
I think this might be the issue here
https://github.com/robconery/moebius/blob/master/lib/moebius/extensions/date_extension.ex#L21
There is no encode/4
to handle binaries only %Postgrex.Date{}
,
%Postgrex.Time{}
, and %Postgrex.Timestamp{}
from moebius.
@robconery I can get this fixed later today.
from moebius.
One note: if you changed it to
{:moebius, "~> 2.0"}
it will grab the latest 2.0.* release :)
Good to know, thanks @nurugger07 👍
from moebius.
Is it worth updating the docs with that @nurugger07? I can do that if you think it's worthwhile.
from moebius.
I can go ahead and make that change when I update the code :)
from moebius.
👍 :)
from moebius.
Just to follow up. I tried converting the Timex.DateTime
to a Timex.Date
and that doesn't work either.
def format_date(date_string) do
Timex.parse(date_string, "%Y-%m-%dT00:00:00.000Z", :strftime)
|> elem(1)
|> Timex.to_timestamp
|> Timex.Date.from_timestamp
end
** (FunctionClauseError) no function clause matching in Moebius.Extensions.DateExtension.encode/4
(moebius) lib/moebius/extensions/date_extension.ex:27: Moebius.Extensions.DateExtension.encode(%Postgrex.TypeInfo{array_elem: 0, base_type: 0, comp_elems: [], input: "date_in", oid: 1082, output: "date_out", receive: "date_recv", send: "date_send", type: "date"}, #<Date(2016-07-21)>, 3678249, nil)
(postgrex) lib/postgrex/query.ex:100: DBConnection.Query.Postgrex.Query.do_encode/4
(postgrex) lib/postgrex/query.ex:61: DBConnection.Query.Postgrex.Query.encode/3
(db_connection) lib/db_connection.ex:885: DBConnection.describe_execute/5
(db_connection) lib/db_connection.ex:1009: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:957: DBConnection.run_meter/3
(db_connection) lib/db_connection.ex:421: DBConnection.query/4
(postgrex) lib/postgrex.ex:111: Postgrex.query/4
from moebius.
Sorry for the delay @jordelver. I've been deep in Date-land and will get this addressed
from moebius.
No problem @nurugger07, I have a workaround so I'm good for now 👍 Will the introduction of new date types in Elixir 1.3 affect this?
from moebius.
Possibly but most likely not right away. That would force an upgrade to 1.3 and although I think it's a good idea to encourage upgrading, it might not be wise to force it yet. That being said, the decision would fall to @robconery.
from moebius.
👍
from moebius.
Just pushed a fix...
from moebius.
v2.0.3 should address this.
from moebius.
Thanks @robconery but unfortunately not :(
I ran mix deps.update moebius
and then checked my mix.lock
to make sure the new version is there
- "moebius": {:hex, :moebius, "2.0.2", "41e53b4c7f7caed0eda4554c705cfd053810c6e8b20e2bcb7c831d9e307a0547", [:mix], [{:timex, "~> 2.0", [hex: :timex, optional: false]}, {:postgrex, "~> 0.11.0", [hex: :postgrex, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:poison, "~> 2.0.1", [hex: :poison, optional: true]}, {:inflex, "~> 1.5.0", [hex: :inflex, optional: false]}]},
+ "moebius": {:hex, :moebius, "2.0.3", "5cd3c60c685876253edff169f55aab600cb6b73d50166364f13b90a904409998", [:mix], [{:inflex, "~> 1.5.0", [hex: :inflex, optional: false]}, {:poison, "~> 2.0.1", [hex: :poison, optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}, {:postgrex, "~> 0.11.0", [hex: :postgrex, optional: false]}, {:timex, "~> 2.0", [hex: :timex, optional: false]}]},
I then tried again and I get the same error
** (FunctionClauseError) no function clause matching in Moebius.Extensions.DateExtension.encode/4
(moebius) lib/moebius/extensions/date_extension.ex:24: Moebius.Extensions.DateExtension.encode(%Postgrex.TypeInfo{array_elem: 0, base_type: 0, comp_elems: [], input: "date_in", oid: 1082, output: "date_out", receive: "date_recv", send: "date_send", type: "date"}, "2016-07-22", 135217, nil)
(postgrex) lib/postgrex/query.ex:131: DBConnection.Query.Postgrex.Query.do_encode/4
(postgrex) lib/postgrex/query.ex:68: DBConnection.Query.Postgrex.Query.encode/3
(db_connection) lib/db_connection.ex:801: DBConnection.describe_execute/4
(db_connection) lib/db_connection.ex:897: DBConnection.run_begin/3
(db_connection) lib/db_connection.ex:845: DBConnection.run_meter/3
(db_connection) lib/db_connection.ex:464: DBConnection.prepare_execute/4
(postgrex) lib/postgrex.ex:117: Postgrex.query/4
from moebius.
Sigh. Dates. WTF.
from moebius.
I know, right :(
I realised that I wasn't passing a date, it was a string, however changing this didn't make it work :(
I just pulled down the code and hooked it up to my app. I added a function to match what I was passing in.
def encode(%Postgrex.TypeInfo{type: "date"}, date, _, _) do
[year, month, day] = String.split(date, "-") |> Enum.map(fn(string) -> {integer, _} = Integer.parse(string); integer end)
<<:calendar.date_to_gregorian_days({year, month, day}) - @gd_epoch :: int32>>
end
This works when I pass in a string like "2016-07-26".
Do we need encode
functions like this for strings and for date structs?
from moebius.
Using Timex 2.0 (for compatibility with this library), for example
{:ok, ts} = Timex.parse("2016-02-29T12:30:30+00:00", "{ISO:Extended}")
Causes the following error
(FunctionClauseError) no function clause matching in Moebius.Extensions.DateExtension.encode/4
(moebius) lib/moebius/extensions/date_extension.ex:24: Moebius.Extensions.DateExtension.encode(%Postgrex.TypeInfo{array_elem: 0, base_type: 0, comp_elems: [], input: "timestamptz_in", oid: 1184, output: "timestamptz_out", receive: "timestamptz_recv", send: "timestamptz_send", type: "timestamptz"}, #<DateTime(2016-02-29T12:30:30Z)>, 6574138, nil)
Judging by the source of the encode/4 function and this discussion thread, should I be assuming that I can't use a Timex type with a TIMESTAMPTZ column?
from moebius.
You can ... sigh this is a mess. It's not matching properly on the string you're passing in. This whole issue is gigantic headache - now that dates are part of Elixir, my only recourse for fixing this is to bump to v3 because I'll have a dependence on Elixir 1.4 :(.
I just need to find the time to hose everything down and put it all together, which I just don't have at the moment.
To directly answer your question: you can see our date tests here and the formats we use:
https://github.com/robconery/moebius/blob/master/test/moebius/date_test.exs
I only use timestamptz so you should be able to get this to work. Sigh.
from moebius.
@robconery Many thanks for your input - I get your frustration - being the maintainer of an open source project people are using in production can be quite a thankless task - people don't appreciate how much effort is required to keep stuff stable in a fluid environment.
The other issue is that time and date handling is the gnarliest part of writing software and people always underestimate how hard it is to get right.
Regarding the string I'm passing in - I actually passed it pre-parsed as a Timex struct, to avoid string interpolation inside moebius.
So I can take a look at the pattern matching required to get this going. Ideally it would be nice to use the current versions of Timex or the 1.4 types. But that would require somebody to help out and push this forward.
For now I think I will try to work around this issue by passing strings to the DB and have the DB convert these to timestamps. It's a bit hacky but it might be the most immediate solution for my current problem.
from moebius.
Jumping back in on this, I'm using the #84 branch in a "semi-production" environment (live, but not user facing), and it seems to be holding up well.
That said, when I wrote those changes, it was targeted at Elixir 1.3 and Postgrex 0.12.1, and it turns out that Elixir 1.3 can't handle datetimes prior to the Unix epoch (1970-01-01). I'm now running it with 1.4, which works fine, but I'd like to bump it up to Postgrex 0.13 when I get a chance, as they've further improved the datetime handling at their end.
from moebius.
@gtebbutt Very cool! Are you planning to refresh #84 or start a new patch?
from moebius.
I'll refresh the existing PR, it should build on the same code - no promises on when I'll have a chance to get to it, unfortunately, though!
from moebius.
Closing as this is handled in v3
from moebius.
Related Issues (20)
- Update library HOT 5
- Make PostgresTypes configurable HOT 1
- Any plans of going to postgres 0.16.x HOT 6
- How do I ACTUALLY use it HOT 7
- Inflex not loading
- Does Moebius sanitize user input? HOT 5
- What does this error mean? HOT 12
- Hang problem. HOT 1
- run_with_psql doesn't use the configured connection info HOT 3
- Updating array column: HOT 8
- readme talks about existence operator, but doesn't show it? HOT 4
- Async test HOT 2
- `pool_mod` option does not work HOT 11
- Allow caching query information
- Is is possible to run moebius and ecto together? HOT 1
- Return values for IO actions HOT 2
- Dependency conflict with phoenix in umbrella app HOT 1
- Date Test Fails
- Moebius.DocumentQuery return only one entry? HOT 3
- limit not being honored alongside search HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from moebius.