martsberger / django-pivot

A module for pivoting Django Querysets
MIT License
210 stars 16 forks source link

unexpected type conversion #10

Closed rorosentrater closed 5 years ago

rorosentrater commented 5 years ago

Hi, I am using this library to pivot my tables, but without any sort of data aggregation. I noticed that when I use a CharField as the 4th parameter (data) I get some unexpected type conversion in my results. Take the following sample data. This is what my DB looks like:

id label value category_id sku_id
1 weight 40lbs 1 5
3 height 10in 1 5
5 power cord 3 prong 3 5
2 weight 20lbs 1 6
4 weight 10lbs 1 8

When I run this command: pivot_table = pivot(SkuData, 'sku_id', 'label', 'value')

The output seems to be forcing all of my strings into a double:

{'sku': 5, 'height': 10.0, 'power cord': 3.0, 'weight': 40.0},
{'sku': 6, 'height': None, 'power cord': None, 'weight': 20.0},
{'sku': 8, 'height': None, 'power cord': None, 'weight': 10.0}

The issue is especially visible for the value of "power cord." which is changed from the string "3 prong" to the double 3.0.

Is this intended functionality?

rorosentrater commented 5 years ago

OK after doing some more research I realize now that this a bit of a loaded question. I neglected the fact that most people doing this are probably aggregating things too. So for example, unless you have DB constraints you could get more than 1 result querying whatever you set as your "rows" and "column" parameters. In that case, I get the need for aggregation because the collection of those matching values need to be distilled down into 1 so that a single value can be used for the cell.

But say you did have DB constraints in place. Meaning that you only ever got 1 result for each "rows" + "column" query, is there no easy way to display just that value?

rafal-jaworski commented 5 years ago

For this i am using string aggregation from postgresql.

rorosentrater commented 5 years ago

I found a hack.

pivot_table = pivot(SkuData, 'sku', 'label', 'value', aggregation=Max)

Since my DB constraints ensure there is only ever 1 result, you can safely use the Max or Min aggregate which (since it's the only value) will give you the actual value of the matching field (normally fieldS), with no type conversion. I have not tested this with all table data types though so your mileage may vary.