Skip to content

Instantly share code, notes, and snippets.

@Fedalto
Created August 3, 2017 21:35
Show Gist options
  • Save Fedalto/f27f4a2bae1f86e70e6e79f99baefe3d to your computer and use it in GitHub Desktop.
Save Fedalto/f27f4a2bae1f86e70e6e79f99baefe3d to your computer and use it in GitHub Desktop.
Handling money with Python and py-moneyed
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is just a spike on handling money with Python and [py-moneyed](https://github.com/limist/py-moneyed).\n",
"\n",
"Just a setup, I created a test table in PostgreSQL with:\n",
"```sql\n",
"CREATE TABLE py_moneyed_test (\n",
" id serial PRIMARY key,\n",
" price_amount NUMERIC,\n",
" price_currency char(3)\n",
")\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from moneyed import Money as BaseMoney\n",
"\n",
"\n",
"class Money(BaseMoney):\n",
" # This is needed to be able to use sqlalchemy composite values\n",
" # We have to use this class instead of moneyed.Money in the codebase\n",
" def __composite_values__(self):\n",
" return self.amount, self.currency.code"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from sqlalchemy import create_engine, Column, Numeric, String, Integer\n",
"from sqlalchemy.orm import composite, sessionmaker\n",
"from sqlalchemy.ext.declarative import declarative_base\n",
"\n",
"engine = create_engine('postgresql://postgres:password@localhost/money_test')\n",
"Session = sessionmaker(bind=engine)\n",
"session = Session()\n",
"\n",
"Base = declarative_base()\n",
"\n",
"\n",
"class PricedItem(Base):\n",
" __tablename__ = 'py_moneyed_test'\n",
"\n",
" id = Column(Integer, primary_key=True)\n",
" price_amount = Column(Numeric)\n",
" price_currency = Column(String(3))\n",
"\n",
" price = composite(Money, price_amount, price_currency)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"some_price = Money(59.50, 'USD')\n",
"item = PricedItem()\n",
"item.price = some_price\n",
"session.add(item)\n",
"session.commit()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Money: 59.5 USD>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fetched_obj = session.query(PricedItem).all()[-1]\n",
"fetched_obj.price"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fetched_obj.price == some_price"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Money: 80.49 USD>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"some_price + Money('20.99', 'USD')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment