require works well in sqlalchemy storage

This commit is contained in:
2014-01-27 17:16:05 +01:00
parent d3f42efe85
commit a1dd2cfce7
4 changed files with 167 additions and 109 deletions

View File

@ -20,10 +20,12 @@
from tiramisu.i18n import _
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy import create_engine, Column, Integer, String, Boolean, \
PickleType, ForeignKey, Table
from sqlalchemy.orm import relationship, backref
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.collections import attribute_mapped_collection
#FIXME
@ -39,68 +41,91 @@ SqlAlchemyBase = declarative_base()
#_Base : object dans la base de donnée
# => _RequireOption => il y a une liste d'espect dans _RequireExpected
# => _PropertyOption => liste des propriétés
# => _Information => dictionnaire avec clef valeur
# => _CallbackParam avec des Options
require_table = Table('require', SqlAlchemyBase.metadata,
Column('left_id', Integer, ForeignKey('requireoption.id')),
Column('right_id', Integer, ForeignKey('baseoption.id'))
)
def load_requires(collection_type, proxy):
def getter(obj):
if obj is None:
return None
ret = []
requires = getattr(obj, proxy.value_attr)
for require in requires:
option = session.query(_Base).filter_by(id=require.option).first()
ret.append(tuple([option, require.expected, require.action, require.inverse, require.transitive, require.same_action]))
return tuple(ret)
def setter(obj, value):
setattr(obj, proxy.value_attr, value)
return getter, setter
class _RequireExpected(SqlAlchemyBase):
__tablename__ = 'expected'
class _Require(SqlAlchemyBase):
__tablename__ = "require"
id = Column(Integer, primary_key=True)
expected = Column(PickleType)
require = Column(Integer, ForeignKey('requireoption.id'))
requires_id = Column(Integer, ForeignKey("baseoption.id"), nullable=False)
requires = relationship('_RequireOption')
def __init__(self, expected):
self.expected = expected
def __init__(self, requires):
for require in requires:
self.requires.append(_RequireOption(require))
class _RequireOption(SqlAlchemyBase):
__tablename__ = 'requireoption'
id = Column(Integer, primary_key=True)
option = relationship('_Base', lazy='joined', cascade="all, delete-orphan")
#option = relationship('_Base')
expected = relationship("_RequireExpected")
require_id = Column(Integer, ForeignKey("require.id"), nullable=False)
option = Column(Integer, nullable=False)
_expected = relationship("_RequireExpected", collection_class=list,
cascade="all, delete-orphan")
expected = association_proxy("_expected", "expected")
#expected = Column(String)
action = Column(String, nullable=False)
inverse = Column(Boolean, default=False)
transitive = Column(Boolean, default=True)
same_action = Column(Boolean, default=True)
def __init__(self, option, expected, action, inverse, transitive,
same_action):
#self.r_opt = option.id
self.option = option
for expect in expected:
self.expected.append(_RequireExpected(expect))
def __init__(self, values):
option, expected, action, inverse, transitive, same_action = values
self.option = option.id
self.expected = expected
self.action = action
self.inverse = inverse
self.transitive = transitive
self.same_action = same_action
def get_expected(self):
for expected in self.expected:
yield(expected.expected)
#def get_option(self, config):
# return config.cfgimpl_get_description().impl_get_opt_by_id(self.r_opt)
class _RequireExpected(SqlAlchemyBase):
__tablename__ = 'expected'
id = Column(Integer, primary_key=True)
require = Column(Integer, ForeignKey('requireoption.id'), nullable=False)
expected = Column(PickleType)
def __init__(self, expected):
#FIXME ne pas creer plusieurs fois la meme _expected_
#FIXME pareil avec calc_properties
self.expected = expected
class _CalcProperties(SqlAlchemyBase):
__tablename__ = 'calcproperty'
id = Column(Integer, primary_key=True)
require = Column(Integer, ForeignKey('baseoption.id'), nullable=False)
name = Column(PickleType)
def __init__(self, name):
#FIXME ne pas creer plusieurs fois la meme _expected_
#FIXME pareil avec calc_properties
self.name = name
#____________________________________________________________
#
# properties
property_table = Table('property', SqlAlchemyBase.metadata,
Column('left_id', Integer, ForeignKey('propertyoption.name')),
Column('right_id', Integer, ForeignKey('baseoption.id'))
)
class _PropertyOption(SqlAlchemyBase):
__tablename__ = 'propertyoption'
name = Column(String, primary_key=True)
id = Column(Integer, primary_key=True)
option = Column(Integer, ForeignKey('baseoption.id'), nullable=False)
name = Column(String)
def __init__(self, name):
self.name = name
@ -112,7 +137,7 @@ class _PropertyOption(SqlAlchemyBase):
class _Information(SqlAlchemyBase):
__tablename__ = 'information'
id = Column(Integer, primary_key=True)
option = Column(Integer, ForeignKey('baseoption.id'))
option = Column(Integer, ForeignKey('baseoption.id'), nullable=False)
key = Column(String)
value = Column(PickleType)
@ -184,11 +209,15 @@ class _Base(SqlAlchemyBase):
__tablename__ = 'baseoption'
id = Column(Integer, primary_key=True)
_name = Column(String)
_informations = relationship('_Information')
#FIXME not autoload
_infos = relationship("_Information",
collection_class=attribute_mapped_collection('key'),
cascade="all, delete-orphan")
_informations = association_proxy("_infos", "value")
_default = Column(PickleType)
_default_multi = Column(PickleType)
_requires = relationship('_RequireOption', secondary=require_table,
backref=backref('self_option', enable_typechecks=False))
_reqs = relationship("_Require", collection_class=list)
_requires = association_proxy("_reqs", "requires", getset_factory=load_requires)
_multi = Column(Boolean)
_multitype = Column(String)
_callback = Column(PickleType)
@ -197,8 +226,14 @@ class _Base(SqlAlchemyBase):
_validator_params = relationship('_CallbackParam')
_parent = Column(Integer, ForeignKey('baseoption.id'))
_children = relationship('BaseOption', enable_typechecks=False)
_properties = relationship('_PropertyOption', secondary=property_table,
backref=backref('options', enable_typechecks=False))
#FIXME pas 2 fois la meme properties dans la base ...
#FIXME not autoload
#FIXME normalement tuple ... transforme en set !
_props = relationship("_PropertyOption", collection_class=set)
_properties = association_proxy("_props", "name")
#FIXME fusion avec expected
_calc_props = relationship("_CalcProperties", collection_class=set)
_calc_properties = association_proxy("_calc_props", "name")
_warnings_only = Column(Boolean)
_readonly = Column(Boolean, default=False)
_consistencies = relationship('_Consistency', secondary=consistency_table,
@ -206,7 +241,6 @@ class _Base(SqlAlchemyBase):
_choice_values = Column(PickleType)
_choice_open_values = Column(Boolean)
_type = Column(String(50))
_r_option = Column(Integer, ForeignKey('requireoption.id'))
__mapper_args__ = {
'polymorphic_identity': 'option',
'polymorphic_on': _type
@ -227,8 +261,8 @@ class _Base(SqlAlchemyBase):
prop_obj = _PropertyOption(propname)
return prop_obj
def _add_require(self, require):
self._requires.append(_RequireOption(*require))
#def _add_require(self, require):
# self._requires.append(_RequireOption(*require))
def _add_callback(self, key, values):
self._callback_params.append(_CallbackParam(key, values))
@ -282,7 +316,6 @@ class StorageOptionDescription(object):
def impl_get_path_by_opt(self, opt):
try:
print opt, type(opt)
return self._cache_paths[1][self._cache_paths[0].index(opt.id)]
except ValueError:
raise AttributeError(_('no option {0} found').format(opt))