Giter Club home page Giter Club logo

Comments (31)

gtebbutt avatar gtebbutt commented on July 16, 2024 1

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.

robconery avatar robconery commented on July 16, 2024

I just pushed 2.0.2 which @nurugger07 fixed RE dates etc. Out of curiosity - did you try :now ?

from moebius.

jordelver avatar jordelver commented on July 16, 2024

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.

robconery avatar robconery commented on July 16, 2024

Just to be sure: you updated the version in mix.exs right?

from moebius.

robconery avatar robconery commented on July 16, 2024

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.

jordelver avatar jordelver commented on July 16, 2024

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.

robconery avatar robconery commented on July 16, 2024

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.

jordelver avatar jordelver commented on July 16, 2024

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.

nurugger07 avatar nurugger07 commented on July 16, 2024

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.

nurugger07 avatar nurugger07 commented on July 16, 2024

@robconery I can get this fixed later today.

from moebius.

jordelver avatar jordelver commented on July 16, 2024

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.

jordelver avatar jordelver commented on July 16, 2024

Is it worth updating the docs with that @nurugger07? I can do that if you think it's worthwhile.

from moebius.

nurugger07 avatar nurugger07 commented on July 16, 2024

I can go ahead and make that change when I update the code :)

from moebius.

jordelver avatar jordelver commented on July 16, 2024

👍 :)

from moebius.

jordelver avatar jordelver commented on July 16, 2024

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.

nurugger07 avatar nurugger07 commented on July 16, 2024

Sorry for the delay @jordelver. I've been deep in Date-land and will get this addressed

from moebius.

jordelver avatar jordelver commented on July 16, 2024

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.

nurugger07 avatar nurugger07 commented on July 16, 2024

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.

jordelver avatar jordelver commented on July 16, 2024

👍

from moebius.

robconery avatar robconery commented on July 16, 2024

Just pushed a fix...

from moebius.

robconery avatar robconery commented on July 16, 2024

v2.0.3 should address this.

from moebius.

jordelver avatar jordelver commented on July 16, 2024

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.

robconery avatar robconery commented on July 16, 2024

Sigh. Dates. WTF.

from moebius.

jordelver avatar jordelver commented on July 16, 2024

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.

0x6e6562 avatar 0x6e6562 commented on July 16, 2024

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.

robconery avatar robconery commented on July 16, 2024

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.

0x6e6562 avatar 0x6e6562 commented on July 16, 2024

@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.

gtebbutt avatar gtebbutt commented on July 16, 2024

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.

0x6e6562 avatar 0x6e6562 commented on July 16, 2024

@gtebbutt Very cool! Are you planning to refresh #84 or start a new patch?

from moebius.

gtebbutt avatar gtebbutt commented on July 16, 2024

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.

robconery avatar robconery commented on July 16, 2024

Closing as this is handled in v3

from moebius.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.