diff options
author | Elrond <elrond+mediagoblin.org@samba-tng.org> | 2013-02-01 15:42:44 +0100 |
---|---|---|
committer | Elrond <elrond+mediagoblin.org@samba-tng.org> | 2013-02-01 22:02:35 +0100 |
commit | 57f8d263e1773be7458f09f9b3f1b7571cb0e026 (patch) | |
tree | 2699786545edb496cb7089e71cb1bc76b9989dad /mediagoblin/db/models.py | |
parent | d728c636b987fa774948ffc122fd080153d8f906 (diff) | |
download | mediagoblin-57f8d263e1773be7458f09f9b3f1b7571cb0e026.tar.lz mediagoblin-57f8d263e1773be7458f09f9b3f1b7571cb0e026.tar.xz mediagoblin-57f8d263e1773be7458f09f9b3f1b7571cb0e026.zip |
Rewrite media_data handling to use relationships
Instead of doing query by hand, use the relationships on
the models to find the media_data. Is is made possible by
the BACKREF_NAME in each models.py, which lets us know the
local attr to ask for.
Also initialize the relationship attribute on new
media_data instead of the media_id. Also do not add it to
the session. This gives us:
- This automatically initializes the other side of the
relationship, which will allow later acces via that way.
- If the media_data is too early in the session, when the
(new) media_entry is not yet in there, this could get
conflicts. Avoid those by not adding to session.
- Uses cascading to commit media_data together with the
media_entry.
Diffstat (limited to 'mediagoblin/db/models.py')
-rw-r--r-- | mediagoblin/db/models.py | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 101e7cee..bdd957dd 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -20,7 +20,7 @@ TODO: indexes on foreignkeys, where useful. import logging import datetime -import sys +from collections import Sequence from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \ Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \ @@ -32,9 +32,10 @@ from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.util import memoized_property from mediagoblin.db.extratypes import PathTupleWithSlashes, JSONEncoded -from mediagoblin.db.base import Base, DictReadAttrProxy, Session +from mediagoblin.db.base import Base, DictReadAttrProxy from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin, CollectionMixin, CollectionItemMixin from mediagoblin.tools.files import delete_media_files +from mediagoblin.tools.common import import_component # It's actually kind of annoying how sqlalchemy-migrate does this, if # I understand it right, but whatever. Anyway, don't remove this :P @@ -165,7 +166,6 @@ class MediaEntry(Base, MediaEntryMixin): collections = association_proxy("collections_helper", "in_collection") ## TODO - # media_data # fail_error def get_comments(self, ascending=False): @@ -195,40 +195,41 @@ class MediaEntry(Base, MediaEntryMixin): if media is not None: return media.url_for_self(urlgen) - #@memoized_property @property def media_data(self): - session = Session() - - return session.query(self.media_data_table).filter_by( - media_entry=self.id).first() + r = getattr(self, self.media_data_ref, None) + if isinstance(r, Sequence): + assert len(r) < 2 + if r: + return r[0] + else: + return None + return r def media_data_init(self, **kwargs): """ Initialize or update the contents of a media entry's media_data row """ - session = Session() - - media_data = session.query(self.media_data_table).filter_by( - media_entry=self.id).first() + media_data = self.media_data - # No media data, so actually add a new one if media_data is None: + # No media data, so actually add a new one media_data = self.media_data_table( - media_entry=self.id, **kwargs) - session.add(media_data) - # Update old media data + # Get the relationship set up. + media_data.get_media_entry = self else: + # Update old media data for field, value in kwargs.iteritems(): setattr(media_data, field, value) @memoized_property def media_data_table(self): - # TODO: memoize this - models_module = self.media_type + '.models' - __import__(models_module) - return sys.modules[models_module].DATA_MODEL + return import_component(self.media_type + '.models:DATA_MODEL') + + @memoized_property + def media_data_ref(self): + return import_component(self.media_type + '.models:BACKREF_NAME') def __repr__(self): safe_title = self.title.encode('ascii', 'replace') |