Question

I have a list of products (say diodoes) which have a curve associated to them. For example,

  • Diode 1: curve 1: [(0,1),(1,3),(2,10), ...., (100,0.5)]
  • Diode 2: curve 2: [(0,2),(1,4),(2.1,19), ..., (100,0)]

So for each product there is a curve (with the same x-axis values range(1,100)) but different y-axis values.

My question is what is the best practice to store such data (using Django + PostgreSql) given that I want to calculate things with it later in the views (say the area under the curve, or that curve times another one, etc). I will also be charting it, so the view will have to pull the values.

My first attempts have had various limitations:

  • Naive attempt 1

     # model.py
     for i in range(101):
         name_sects = ["x", str(i+1)]
         attrs["".join(name_sects)] = models.DecimalField(_("".join([str(i+1),' A'])), max_digits=6)
    
    
     attrs['intensity'] = model.DecimalField(_('Diode Intensity'))
    
    
     Diode = type('Diode', (models.Model,), attrs)
    

Ok, that creates a field for each "x", x1, x2,... etc, and I can fill each "y" in the admin ... but it's not obvious how to manipulate it in the view or the template. (and a pain to fill in, obviously)

  • Naive attempt 2

    #model.py
    class Curve(models.Model)
        x_axis = models.PositiveIntegerField( ...)
        y_axis = models.DecimalField( ...)
    
    class Diode(models.Model)
        name = blah, blah
        intensity = model.DecimalField(_('Diode Intensity'), blah, blah)
        characteristic_curve = model.ManyToManyField(Curve)
    

Is ManyToMany the way forward? Even if to each diode corresponds one single curve? (but many points, possibly two diodes sharing a same point).

Any advice, tips or links to tools for it are very appreciated.

Was it helpful?

Solution

If you want to improve speed (because 100 entries for each product, it's really huge and it would be slow if you have to fetch 100 products and theirs points), I would use the pickle module and store your list of tuples in a TextField (or maybe CharField if the length of the string doesn't change).

>>> a = [(1,2),(3,4),(5,6),(7,8)]
>>> pickle.dumps(a)
'(lp0\n(I1\nI2\ntp1\na(I3\nI4\ntp2\na(I5\nI6\ntp3\na(I7\nI8\ntp4\na.'
>>> b = pickle.dumps(a)
>>> pickle.loads(b)
[(1, 2), (3, 4), (5, 6), (7, 8)]

Just store b in your TextField and you can get back your list really easily.

And even better, as Robert Smith says, use http://pypi.python.org/pypi/django-picklefield

OTHER TIPS

I like your second approach but just a minor suggestion.

class Plot(models.Model):
    x_axis = models.PositiveIntegerField( ...)
    y_axis = models.DecimalField( ...)

class Curve(models.Model)
   plots = models.ManyToManyField(Plot)

class Diode(models.Model)
    name = blah, blah
    intensity = model.DecimalField(_('Diode Intensity'), blah, blah)
    curve = models.ForeignKey(Curve)

Just a minor suggestion for flexibility

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top