SQL: fail_metadata as JSON encoded field
authorElrond <elrond+mediagoblin.org@samba-tng.org>
Sun, 12 Feb 2012 22:49:01 +0000 (23:49 +0100)
committerElrond <elrond+mediagoblin.org@samba-tng.org>
Sat, 18 Feb 2012 18:29:01 +0000 (19:29 +0100)
fail_metadata used to be a dict in mongo. So a json encoded
field should be okay too.

We could use a pickled field instead, which would be more
flexible.

mediagoblin/db/sql/convert.py
mediagoblin/db/sql/extratypes.py
mediagoblin/db/sql/models.py

index a46d62ea35e48d280dc226883da82c7e20e97bad..14a0b9117d7073caa7008529dc47fed266f8a706 100644 (file)
@@ -79,7 +79,7 @@ def convert_media_entries(mk_db):
             ('title', 'slug', 'created',
              'description',
              'media_type', 'state', 'license',
-             'fail_error',
+             'fail_error', 'fail_metadata',
              'queued_task_id',))
         copy_reference_attr(entry, new_entry, "uploader")
 
index 3a594728bf5d4785aba387b2df93ecf6bb819fcf..8e078f14a32100d6ea38d43fb02545d8d6224f1f 100644 (file)
@@ -15,7 +15,8 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
-from sqlalchemy.types import TypeDecorator, Unicode
+from sqlalchemy.types import TypeDecorator, Unicode, VARCHAR
+import json
 
 
 class PathTupleWithSlashes(TypeDecorator):
@@ -35,3 +36,28 @@ class PathTupleWithSlashes(TypeDecorator):
         if value is not None:
             value = tuple(value.split('/'))
         return value
+
+
+# The following class and only this one class is in very
+# large parts based on example code from sqlalchemy.
+#
+# The original copyright notice and license follows:
+#     Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file>
+#
+#     This module is part of SQLAlchemy and is released under
+#     the MIT License: http://www.opensource.org/licenses/mit-license.php
+#
+class JSONEncoded(TypeDecorator):
+    "Represents an immutable structure as a json-encoded string."
+
+    impl = VARCHAR
+
+    def process_bind_param(self, value, dialect):
+        if value is not None:
+            value = json.dumps(value)
+        return value
+
+    def process_result_value(self, value, dialect):
+        if value is not None:
+            value = json.loads(value)
+        return value
index 18e1dfd7453612d1d2704729a0371e6461482ce0..a34ff3bcfd8fe1e19992dc70e4455b30f7ea0c1d 100644 (file)
@@ -29,7 +29,7 @@ from sqlalchemy.orm.collections import attribute_mapped_collection
 from sqlalchemy.sql.expression import desc
 from sqlalchemy.ext.associationproxy import association_proxy
 
-from mediagoblin.db.sql.extratypes import PathTupleWithSlashes
+from mediagoblin.db.sql.extratypes import PathTupleWithSlashes, JSONEncoded
 from mediagoblin.db.sql.base import Base, DictReadAttrProxy
 from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin
 
@@ -91,7 +91,7 @@ class MediaEntry(Base, MediaEntryMixin):
     license = Column(Unicode)
 
     fail_error = Column(Unicode)
-    fail_metadata = Column(UnicodeText)
+    fail_metadata = Column(JSONEncoded)
 
     queued_media_file = Column(PathTupleWithSlashes)