Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices for doing accounting in Python

I am writing a web2py application that requires summing dollar amounts without losing precision. I realize I need to use Decimals for this, but I've found myself having to wrap every single number I get from the database with:

Decimal(str(myval))

Before I go crazy adding that to all of my code, is there a better way? I'm new to Python, so it's very possible that I am overlooking something obvious.

Edit: My database is MS SQL Server and I'm storing the amounts in SQL Server money fields (I believe the implementation is analogous to Decimal, ie integer math, not floating point).

I am connecting to the db through the web2py framework (which uses pyodbc for SQL Server connections). I believe web2py has some support for decimal types. For example, my web2py field definitions look like: Field('Amount','decimal(19,4)') However, when I return a value from the database using web2py's .executesql method it returns the value as a float and not a Decimal.

Edit: This appears to be an issue with FreeTDS and MS SQL Server. As Massimo stated in the comments, web2py supports this properly and returns a Decimal (if it can). It turns out this is only an issue in my production environment (Linux). I am using the FreeTDS driver to connect to MS SQL and it appears to be translating the MS SQL money type to a python float.

I think Alex Martelli's answer is pointing in the right direction. Does anyone have any experience with FreeTDS, MS SQL, and python? I think this probably warrants its own question, so I'll move this discussion... (new question posted here: FreeTDS translating MS SQL money type to python float, not Decimal)

Update: There was in fact a bug in FreeTDS. This was fixed in the CVS head of FreeTDS as of August 4, 2010.

like image 394
mwolfe02 Avatar asked Jul 29 '10 16:07

mwolfe02


People also ask

How can Python be used in accounting?

From an accountancy perspective, Python is most useful when working with data. It can essentially read any type, both structured and unstructured. It has powerful capabilities in data importation and manipulation – tasks like merging and recoding – as well as handling large amounts.

Is Python worth learning for accounting?

Based on my research, Python seemed to be the most recommended language for accountants as some say Python is the easiest to learn. On top of that, there is a lot of Python resource out there that works with Excel (aka accountant's favourite software).

Can you automate accounting with Python?

Most important for accountants, Python can automate recurring tasks. The more often the data manipulation is required, the more value Python automation will provide.

How do finance professionals use Python?

Python is widely used in quantitative finance - solutions that process and analyze large datasets, big financial data. Libraries such as Pandas simplify the process of data visualization and allow carrying out sophisticated statistical calculations.


1 Answers

First, keep all numbers in decimal form in the database -- you don't mention what DB engine you're using, but every engine supports such functionality, e.g., here is MySQL's DECIMAL type documentation. I hope you're already doing that, but, if you aren't, it's still worth the pain of a schema change.

Then, you need to ensure the type conversion to and from the DB matches the database's decimals with Python's. Unfortunately there is no standard way to do it across DB-API implementations, but most do offer a way; for example, with MySQLDB you need to pass a conv= parameter in connect, known as a "type converters dictionary" -- the default is a copy of MySQLdb.converters.conversions but of course you can enrich it to do the right thing with decimals. If you tell us which DB you're using, and what DB-API connector package you prefer for it, we may be able to give you more detailed help on this subject.

Edit: @unutbu remarks in a comment that the current MySQLdb converter already does translate decimals correctly, so, unless you're stuck with a very old release of MySQLdb, you should be fine as long as you do correctly keep all the numbers as decimal in the DB (yay!).

like image 145
Alex Martelli Avatar answered Sep 28 '22 21:09

Alex Martelli