]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- the Binary type now returns data as a Python string
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 5 Sep 2009 03:29:20 +0000 (03:29 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 5 Sep 2009 03:29:20 +0000 (03:29 +0000)
(or a "bytes" type in Python 3), instead of the built-
in "buffer" type.  This allows symmetric round trips
of binary data. [ticket:1524]

CHANGES
lib/sqlalchemy/dialects/mysql/base.py
lib/sqlalchemy/types.py
test/orm/test_unitofwork.py
test/sql/test_types.py

diff --git a/CHANGES b/CHANGES
index e2bd8f8933223bab9857241a54cb4aac369db688..68dd7cbe02e86936d4db7591afddff25340d538a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -85,6 +85,11 @@ CHANGES
     - the last_inserted_ids() method has been renamed to the
       descriptor "inserted_primary_key".
 
+    - the Binary type now returns data as a Python string
+      (or a "bytes" type in Python 3), instead of the built-
+      in "buffer" type.  This allows symmetric round trips
+      of binary data. [ticket:1524]
+      
     - User-defined "default" and "onupdate" callables which 
       accept a context should now call upon 
       "context.current_parameters" to get at the dictionary
index 4700a7b4ffc4f80952eb5ba2769674ba5bf4e4ad..aa616efdf37e5568635e9415e631d3515be97fe8 100644 (file)
@@ -301,13 +301,7 @@ class _StringType(sqltypes.String):
 class _BinaryType(sqltypes.Binary):
     """Base for MySQL binary types."""
 
-    def result_processor(self, dialect):
-        def process(value):
-            if value is None:
-                return None
-            else:
-                return util.buffer(value)
-        return process
+    pass
 
 class NUMERIC(_NumericType, sqltypes.NUMERIC):
     """MySQL NUMERIC type."""
index 1b2c72bc7d0901ee226f0d2d2446a4a60720e8e5..8b847f201481b7769e8c7c178252aac8eab66d42 100644 (file)
@@ -778,6 +778,14 @@ class Binary(TypeEngine):
                 return None
         return process
 
+    def result_processor(self, dialect):
+        def process(value):
+            if value is not None:
+                return str(value)
+            else:
+                return None
+        return process
+
     def adapt(self, impltype):
         return impltype(length=self.length)
 
index 4d2056b264f26c491216a814471a788d5b291d20..cdf6d39b943c33ee6837b402dddb91b16aae8bdd 100644 (file)
@@ -304,7 +304,41 @@ class UnicodeSchemaTest(engine_base.AltEngineTest, _base.MappedTest):
 
         eq_([A(b=5), B(e=7)], session.query(A).all())
 
+class BinaryHistTest(_base.MappedTest, testing.AssertsExecutionResults):
+    @classmethod
+    def define_tables(cls, metadata):
+        Table('t1', metadata,
+            Column('id', sa.Integer, primary_key=True),
+            Column('data', sa.Binary),
+        )
+
+    @classmethod
+    def setup_classes(cls):
+        class Foo(_base.BasicEntity):
+            pass
 
+    @testing.resolve_artifact_names
+    def test_binary_equality(self):
+        
+        mapper(Foo, t1)
+        
+        s = create_session()
+        
+        f1 = Foo(data="this is some data")
+        s.add(f1)
+        s.flush()
+        s.expire_all()
+        f1 = s.query(Foo).first()
+        assert f1.data == "this is some data"
+        f1.data = "this is some data"
+        eq_(
+            sa.orm.attributes.get_history(f1, "data"),
+            ((), ["this is some data"], ())
+        )
+        def go():
+            s.flush()
+        self.assert_sql_count(testing.db, go, 0)
+        
 class MutableTypesTest(_base.MappedTest):
 
     @classmethod
index cede11cc5ffbb2782264dfa50a04a6c54bf0bb14..f57347115e706e4764b6f843a75f2257d989280e 100644 (file)
@@ -401,21 +401,29 @@ class BinaryTest(TestBase, AssertsExecutionResults):
 
         for stmt in (
             binary_table.select(order_by=binary_table.c.primary_id),
-            text("select * from binary_table order by binary_table.primary_id", typemap={'pickled':PickleType, 'mypickle':MyPickleType}, bind=testing.db)
+            text(
+                "select * from binary_table order by binary_table.primary_id", 
+                typemap={'pickled':PickleType, 'mypickle':MyPickleType, 'data':Binary, 'data_slice':Binary}, 
+                bind=testing.db)
         ):
-            eq_data = lambda x, y: eq_(list(x), list(y))
-            if util.jython:
-                _eq_data = eq_data
-                def eq_data(x, y):
-                    # Jython currently returns arrays
-                    from array import ArrayType
-                    if isinstance(y, ArrayType):
-                        return eq_(x, y.tostring())
-                    return _eq_data(x, y)
+            #if util.jython:
+                # TODO: may need to modify Binary type directly
+                # to detect jython if something other than str()/bytes()
+                # is needed to convert from raw to string/bytes.
+                # ArrayType should no longer be expected here though.
+                # users who want raw ArrayType can of course create their
+                # own BinaryType that does no conversion.
+                #_eq_data = eq_data
+                #def eq_data(x, y):
+                #    # Jython currently returns arrays
+                #    from array import ArrayType
+                #    if isinstance(y, ArrayType):
+                #        return eq_(x, y.tostring())
+                #    return _eq_data(x, y)
             l = stmt.execute().fetchall()
-            eq_data(stream1, l[0]['data'])
-            eq_data(stream1[0:100], l[0]['data_slice'])
-            eq_data(stream2, l[1]['data'])
+            eq_(stream1, l[0]['data'])
+            eq_(stream1[0:100], l[0]['data_slice'])
+            eq_(stream2, l[1]['data'])
             eq_(testobj1, l[0]['pickled'])
             eq_(testobj2, l[1]['pickled'])
             eq_(testobj3.moredata, l[0]['mypickle'].moredata)