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.
This commit is contained in:
parent
d728c636b9
commit
57f8d263e1
@ -20,7 +20,7 @@ TODO: indexes on foreignkeys, where useful.
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import datetime
|
import datetime
|
||||||
import sys
|
from collections import Sequence
|
||||||
|
|
||||||
from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \
|
from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \
|
||||||
Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \
|
Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \
|
||||||
@ -32,9 +32,10 @@ from sqlalchemy.ext.associationproxy import association_proxy
|
|||||||
from sqlalchemy.util import memoized_property
|
from sqlalchemy.util import memoized_property
|
||||||
|
|
||||||
from mediagoblin.db.extratypes import PathTupleWithSlashes, JSONEncoded
|
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.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin, CollectionMixin, CollectionItemMixin
|
||||||
from mediagoblin.tools.files import delete_media_files
|
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
|
# It's actually kind of annoying how sqlalchemy-migrate does this, if
|
||||||
# I understand it right, but whatever. Anyway, don't remove this :P
|
# 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")
|
collections = association_proxy("collections_helper", "in_collection")
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
# media_data
|
|
||||||
# fail_error
|
# fail_error
|
||||||
|
|
||||||
def get_comments(self, ascending=False):
|
def get_comments(self, ascending=False):
|
||||||
@ -195,40 +195,41 @@ class MediaEntry(Base, MediaEntryMixin):
|
|||||||
if media is not None:
|
if media is not None:
|
||||||
return media.url_for_self(urlgen)
|
return media.url_for_self(urlgen)
|
||||||
|
|
||||||
#@memoized_property
|
|
||||||
@property
|
@property
|
||||||
def media_data(self):
|
def media_data(self):
|
||||||
session = Session()
|
r = getattr(self, self.media_data_ref, None)
|
||||||
|
if isinstance(r, Sequence):
|
||||||
return session.query(self.media_data_table).filter_by(
|
assert len(r) < 2
|
||||||
media_entry=self.id).first()
|
if r:
|
||||||
|
return r[0]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
return r
|
||||||
|
|
||||||
def media_data_init(self, **kwargs):
|
def media_data_init(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initialize or update the contents of a media entry's media_data row
|
Initialize or update the contents of a media entry's media_data row
|
||||||
"""
|
"""
|
||||||
session = Session()
|
media_data = self.media_data
|
||||||
|
|
||||||
media_data = session.query(self.media_data_table).filter_by(
|
|
||||||
media_entry=self.id).first()
|
|
||||||
|
|
||||||
# No media data, so actually add a new one
|
|
||||||
if media_data is None:
|
if media_data is None:
|
||||||
|
# No media data, so actually add a new one
|
||||||
media_data = self.media_data_table(
|
media_data = self.media_data_table(
|
||||||
media_entry=self.id,
|
|
||||||
**kwargs)
|
**kwargs)
|
||||||
session.add(media_data)
|
# Get the relationship set up.
|
||||||
# Update old media data
|
media_data.get_media_entry = self
|
||||||
else:
|
else:
|
||||||
|
# Update old media data
|
||||||
for field, value in kwargs.iteritems():
|
for field, value in kwargs.iteritems():
|
||||||
setattr(media_data, field, value)
|
setattr(media_data, field, value)
|
||||||
|
|
||||||
@memoized_property
|
@memoized_property
|
||||||
def media_data_table(self):
|
def media_data_table(self):
|
||||||
# TODO: memoize this
|
return import_component(self.media_type + '.models:DATA_MODEL')
|
||||||
models_module = self.media_type + '.models'
|
|
||||||
__import__(models_module)
|
@memoized_property
|
||||||
return sys.modules[models_module].DATA_MODEL
|
def media_data_ref(self):
|
||||||
|
return import_component(self.media_type + '.models:BACKREF_NAME')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
safe_title = self.title.encode('ascii', 'replace')
|
safe_title = self.title.encode('ascii', 'replace')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user