Hello;

I want to create a custom model field for storing a numpy array. It has 
currently been so simple that I fear I am overrlooking something and 
getting a very false positive?

<code>
class NumpyArrayField(BinaryField):
    dtype = numpy.float32

    @classmethod
    def load_numpy_array(cls , blob):
        return numpy.fromstring(blob , NumpyArrayField.dtype)

    def __init__(self , *args , **kwargs):
        kwargs['default'] = None
        super(NumpyArrayField , self).__init__(*args , **kwargs)


    def from_db_value(self, value, expression, connection, context):
        if value is None:
            return value
        return self.load_numpy_array( value )


    def to_python(self, value):
        if isinstance(value, numpy.ndarray):
            return value

        if value is None:
            return value

        return self.load_numpy_array( value )
</code>

As I see it this has (essenially two versions) of code for deserializing 
from a database value to a numpy array, but no method for the opposite 
operation. However it seemingly works?

I have created a small model with one of these fields:

<code>

class TimeSeries(Model):
    start = DateTimeField( )
    step = IntegerField( )
    data = NumpyArrayField( )


    @classmethod
    def createArray(cls , size = 0):
        return numpy.ndarray( shape = [size] , dtype = 
NumpyArrayField.dtype)

    def __getitem__(self , index):
        if self.data is None:
            raise IndexError
        else:
            return self.data[index]

    def __setitem__(self , index , value):
        if self.data is None:
            raise IndexError
        else:
            self.data[index] = value


    def __len__(self):
        if self.data is None:
            return 0
        else:
            shape = self.data.shape
            return shape[0]

</code>

And a test:

<code>
class TimeSeriesTest(TestCase):

    def test_create(self):
        ts = TimeSeries.objects.create( start = timezone.now(),
                                        step = 100 ,
                                        data = TimeSeries.createArray( ))
        self.assertEqual( len(ts) , 0 )
        with self.assertRaises(IndexError):
            ts[0]        

        ts.addValue( 1 )
        
        self.assertEqual( len(ts) , 1 )
        with self.assertRaises(IndexError):
            ts[1]

        self.assertEqual( ts[0] , 1 )
 
        # How on earth does the NumpyArrayField know how to save itself to 
the db?
        ts.save()

        ts2 = TimeSeries.objects.get( pk = 1 )
        self.assertEqual( ts2[0] , 1)
        self.assertEqual( len(ts2) , 1 )
</code>

I was expecting the test to fail spectacularly when calling ts.save() - 
however it seems to work, and I can even get the instance back from db - 
what gives?  I am using sqlite and have tried to force the db to create a 
file.

I was excpecting to implement the get_prep_db_value() method - but now when 
things seemingly work without it I get quite uncertain? Is there some magic 
trickery involved which says that this should indeed work - or am I seeing 
a completely false positive?

Joakim





-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/09fa67a5-70b6-40c4-a600-13ea9cbbd97c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to