In our August 2008/ September 2008 issue we demonstrated the power of PostgreSQL to create median and MS Access-like first and last aggregate functions in
SQL language.  In this article we shall demonstrate how to create aggregates with Python.  We shall
call this function agg_plot.  What it will do is plot each grouping of data and return a plot for each grouping. The steps
we covered in those articles can be applied here.
For this part, we shall use the same library we discussed in PLPython Part 3: Using custom classes, pulling data from PostgreSQL.
			 
						Creating Aggregate functions with PL/Python
Our basic approach is as follows:
- Since PL/Python does not support arrays as input, our aggregator will form a pipe delimeted list inputs
	as a string using plot_databuild function (which although we wrote it in python need not be and probably more efficient to write in plpgsql
 
	- As the final step of the aggregation, this is fed to our plot_numbers function -- which converts this to an array of strings and then converts to an array of
		numbers to be fed to the plotter
 
Code is shown below and final output
##create agg
CREATE OR REPLACE FUNCTION plot_numbers(param_dataset text)
  RETURNS text AS
 $$
 import aplotter
 import sys
 class WritableObject:
	def __init__(self):
		self.content = ''
	def write(self, string):
		self.content = self.content + string
 saveout = sys.stdout
 outbuffer = WritableObject()
 sys.stdout = outbuffer
 #convert our string of | delimited numbers to an array
 adataset = param_dataset.split('|')
 #pipe in converting each string to number
 aplotter.plot([float(y) for y in adataset])
 sys.stdout = saveout
 return outbuffer.content
$$ LANGUAGE plpythonu;
CREATE OR REPLACE FUNCTION plot_databuild(param_dataset text, param_item numeric)
  RETURNS text AS
 $$
  if param_dataset is None :
	return str(param_item)
  return param_dataset + '|' + str(param_item)
$$ LANGUAGE plpythonu;
CREATE AGGREGATE agg_plot(numeric) (
  SFUNC=plot_databuild,
  STYPE=text,
  FINALFUNC=plot_numbers
);
##Plotting fake data but lets pretend it is real
CREATE TABLE mydata2(pt_id serial, pt_observation numeric(10,4), graph_id integer);
INSERT INTO mydata(pt_observation, graph_id)
	SELECT n*pi()*random()*10, generate_series(1,3)
		FROM generate_series(1,15) As n;
#and now to test
SELECT graph_id, agg_plot(pt_observation)
 FROM mydata2
 GROUP BY graph_id
 ORDER BY graph_id;
Which gives us this:
1; |
   +378.733                                                      \ 
   |                                                            /\          *
   |                                                           /  \        /
   |                                                          /   \        /
   |                                                         /     \      /
   |                                                        /      \      /
   |                                         \              /       \    /
   |                                        / \\           /        \    /
   |                                       /    \\-      //          \  /
   |                         \             /       ----//            \  /
   |                    -----\            /                           \/
   |                   /      \          /                            \/
   |                 //        \         /                             /
   |          -----//           \       /
   |         /                   \      /
   |       //                     ------
   |      /
---+0.86//------------------------------------------------------------------+---
   +0                                                                    +14
2; |
   +333.964                                                            -----*
   |                                                                  /
   |                                                                //
   |                                                               /
   |                                              \              //
   |                                    \        /\             |
   |                                   / \\    // \             |
   |                                  /    \\//    \           |
   |                                 /             \           |
   |                                /               \          |
   |                               /                \         |
   |               \              /                  \        |
   |              / \             /                  \       |
   |             /   \\      -----                    \      |
   |    -       /      \-----                         \      |
   |  -- -----//                                       -    |
   ---                                                  --  |
---+0.26--------------------------------------------------==|---------------+---
   +0                                                                    +14
3; +0                                                                    +14
   +344.31                                             -
   |                                                  | ----|
   |                                                  |     |
   |                                                 |      |
   |                                                 |      |
   |                                                 |       |
   |                                                |        |
   |                                                |        |
   |                                                |         |             *
   |                                               |          |            /
   |                                               |          |          //
   |                                    \          |           |       //
   |                    -              / \        |            |      /
   |                   / --           /   \       |            |     /
   |          \       /    --\       /     \      |             |   /
   |    ------ \\    /        \\    /       \   //              |  /
   |  --         \\//           \\//         ///                | /
   +15.4662                                                      /
---+------------------------------------------------------------------------+---
 
			
			
			
		
In our PLPython Part 4: PLPython meets aggregates we demonstrated the power of PostgreSQL in combination with PLPython to create a sequence of ascii plots by using the power of aggregation. Our friend Simon Greener over at Spatial Db Advisor told me th
Tracked: Mar 12, 13:55
Tracked: Jul 10, 19:39
Tracked: Jul 10, 19:39
Tracked: Jul 10, 19:39