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.mongo.util import ObjectId
from mediagoblin.db.sql.models import (Base, User, MediaEntry, MediaComment, 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 \ from mediagoblin.db.sql.open import setup_connection_and_db_from_config as \
sql_connect sql_connect
from mediagoblin.db.mongo.open import setup_connection_and_db_from_config as \ 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() session.flush()
add_obj_ids(entry, new_entry) 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.commit()
session.close() 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, Column, Integer, Unicode, UnicodeText, DateTime, Boolean, ForeignKey,
UniqueConstraint) UniqueConstraint)
from sqlalchemy.orm import relationship 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.sql.base import GMGTableBase
from mediagoblin.db.mixin import UserMixin, MediaEntryMixin from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
@ -65,7 +68,7 @@ class MediaEntry(Base, MediaEntryMixin):
fail_error = Column(Unicode) fail_error = Column(Unicode)
fail_metadata = Column(UnicodeText) fail_metadata = Column(UnicodeText)
queued_media_file = Column(Unicode) queued_media_file = Column(PathTupleWithSlashes)
queued_task_id = Column(Unicode) queued_task_id = Column(Unicode)
@ -75,13 +78,33 @@ class MediaEntry(Base, MediaEntryMixin):
get_uploader = relationship(User) 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 ## TODO
# media_files
# media_data # media_data
# attachment_files # attachment_files
# fail_error # 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): class Tag(Base):
__tablename__ = "tags" __tablename__ = "tags"