Add MediaFile table and related infrastructure.

- This adds a new SQL table field type for path tuples.
  They're stored as '/' separated unicode strings.

- Uses it to implement a MediaFile table.

- Add relationship and proxy fields on MediaEntry to give a
  nice media_files "view" there.

- Let the converter fill the MediaFile.
This commit is contained in:
Elrond 2011-12-31 23:01:34 +01:00
parent 0ab21f981a
commit 02db7e0a83
3 changed files with 49 additions and 3 deletions

View File

@ -2,7 +2,7 @@ from mediagoblin.init import setup_global_and_app_config, setup_database
from mediagoblin.db.mongo.util import ObjectId
from mediagoblin.db.sql.models import (Base, User, MediaEntry, MediaComment,
Tag, MediaTag)
Tag, MediaTag, MediaFile)
from mediagoblin.db.sql.open import setup_connection_and_db_from_config as \
sql_connect
from mediagoblin.db.mongo.open import setup_connection_and_db_from_config as \
@ -70,6 +70,11 @@ def convert_media_entries(mk_db):
session.flush()
add_obj_ids(entry, new_entry)
for key, value in entry.media_files.iteritems():
new_file = MediaFile(name=key, file_path=value)
new_file.media_entry = new_entry.id
Session.add(new_file)
session.commit()
session.close()

View File

@ -0,0 +1,18 @@
from sqlalchemy.types import TypeDecorator, Unicode
class PathTupleWithSlashes(TypeDecorator):
"Represents a Tuple of strings as a slash separated string."
impl = Unicode
def process_bind_param(self, value, dialect):
if value is not None:
assert len(value), "Does not support empty lists"
value = '/'.join(value)
return value
def process_result_value(self, value, dialect):
if value is not None:
value = tuple(value.split('/'))
return value

View File

@ -5,7 +5,10 @@ from sqlalchemy import (
Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
UniqueConstraint)
from sqlalchemy.orm import relationship
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.ext.associationproxy import association_proxy
from mediagoblin.db.sql.extratypes import PathTupleWithSlashes
from mediagoblin.db.sql.base import GMGTableBase
from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
@ -65,7 +68,7 @@ class MediaEntry(Base, MediaEntryMixin):
fail_error = Column(Unicode)
fail_metadata = Column(UnicodeText)
queued_media_file = Column(Unicode)
queued_media_file = Column(PathTupleWithSlashes)
queued_task_id = Column(Unicode)
@ -75,13 +78,33 @@ class MediaEntry(Base, MediaEntryMixin):
get_uploader = relationship(User)
media_files_helper = relationship("MediaFile",
collection_class=attribute_mapped_collection("name"),
cascade="all, delete-orphan"
)
media_files = association_proxy('media_files_helper', 'file_path',
creator=lambda k,v: MediaFile(name=k, file_path=v)
)
## TODO
# media_files
# media_data
# attachment_files
# fail_error
class MediaFile(Base):
__tablename__ = "mediafiles"
media_entry = Column(
Integer, ForeignKey(MediaEntry.id),
nullable=False, primary_key=True)
name = Column(Unicode, primary_key=True)
file_path = Column(PathTupleWithSlashes)
def __repr__(self):
return "<MediaFile %s: %r>" % (self.name, self.file_path)
class Tag(Base):
__tablename__ = "tags"