Adds PostgreSQL's money
data type support to Postgrex
.
I do integrations, to be more specific, I help my customer to migrate his current ERP-system. The target database is a PostgreSQL database and involves many tables using the money
data type. To my surprise Postgrex
doesn't support this data type... for a good reason. Hence the need for this library.
The usage of money
should be avoided though as explained in the PostgreSQL wiki's Don't do this:
The
money
data type isn't actually very good for storing monetary values.Numeric
, or (rarely)integer
may be better.lots of reasons.
It's a fixed-point type, implemented as a machine int, so arithmetic with it is fast. But it doesn't handle fractions of a cent (or equivalents in other currencies), it's rounding behaviour is probably not what you want.
It doesn't store a currency with the value, rather assuming that all money columns contain the currency specified by the database's lc_monetary locale setting. If you change the
lc_monetary
setting for any reason, allmoney
columns will contain the wrong value. That means that if you insert$10.00
whilelc_monetary
is set toen_US.UTF-8
the value you retrieve may be10,00 Lei
or¥1,000
iflc_monetary
is changed.Storing a value as a
numeric
, possibly with the currency being used in an adjacent column, might be better.If you
- are only working in a single currency
- aren't dealing with fractional cents
- are only doing addition and subtraction
then money might be the right thing.
... so probably never. Read Mathias Verraes' excellent chapter Emergent Contexts through Refinement
in DDD - The First 15 Years to get a better understanding of currencies.
But this flawed type is out there and needs some interfacing, hence this project. See how it fails you in a fail in three acts.
If available in Hex, the package can be installed
by adding pg_money
to your list of dependencies in mix.exs
:
def deps do
[
{:pg_money, "~>0.4.21"}
]
end
Reference it via it's github url:
def deps do
[
{:pg_money, git: "https://github.com/CodeJordan23/pg_money.git", tag: "0.4.21"}
]
end
my_types =
[
{PgMoney.Extension, [precision: 2, telemetry_prefix: [:my, :prefix]]}
]
Postgrex.Types.define(MyApp.PostgresTypes, my_types, [])
opts = [hostname: "localhost", username: "postgres", database: "pg_money_test", types: MyApp.PostgresTypes ]
# or use PgMoney.Type
{:ok, pid} = Postgrex.Connection.start_link(opts)
You will want to add a new file with your type definition like postgres_types.ex
Postgrex.Types.define(MyApp.PostgresTypes,
[{PgMoney.Extension, [precision: 2, telemetry_prefix: [:my, :prefix]]}] ++ Ecto.Adapters.Postgres.extensions(),
[])
and then configure your repository to use it like so:
config :my_app, MyApp.Repo, types: MyApp.PostgresTypes
Head over to Ecto.Adapaters.Postgres
' module extension to learn more.
Copyright 2019 Michael J. Lüttjohann
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
If I have seen further it is by standing on the shoulders of Giants.
- Isaac Newton
I want to mention some of these giants and warmly thank all the people involved:
- PostgreSQL a great and free database. The well written documentation helped me to write the kick-starter tests for this library.
- Postgrex For making it so easy to extend.
- Credo and
mix format
for giving me guidance. - Plataformatec for hooking me on
Elixir
with their little Ecto Cookbook on August 19th. 13 weeks ago... - Mathias Verraes found at his homepage for writing his superb article
Emergent Contexts through Refinement
found here DDD - The First 15 Years and like all the people involved with this book. - the whole
Elixir
ecosystem. It was fun writing this library.- writing documentation was easy and generated easily with
ExDoc
- writing tests was seamless.
- publishing to hexdocs.pm seems straigtforward
- writing documentation was easy and generated easily with
- github.com and hexdocs.pm for hosting this library.