import sqlalchemy.engine as engine
import sqlalchemy.util as util
import objectstore
-
+import sys
mapper_registry = {}
self.copyargs = {
'class_':class_,
'table':table,
- 'primarytable':primarytable,
'properties':properties or {},
'primary_key':primary_key,
'is_primary':None,
'extension':extension,
'order_by':order_by
}
-
+
+ if primarytable is not None:
+ sys.stderr.write("'primarytable' argument to mapper is deprecated\n")
+
if extension is None:
self.extension = MapperExtension()
else:
self.order_by = order_by
if not issubclass(class_, object):
- raise "Class '%s' is not a new-style class" % class_.__name__
-
- if inherits is not None:
- primarytable = inherits.primarytable
- # inherit_condition is optional since the join can figure it out
- table = sql.join(table, inherits.table, inherit_condition)
-
+ raise TypeError("Class '%s' is not a new-style class" % class_.__name__)
+
if isinstance(table, sql.Select):
# some db's, noteably postgres, dont want to select from a select
- # without an alias
- self.table = table.alias(None)
+ # without an alias. also if we make our own alias internally, then
+ # the configured properties on the mapper are not matched against the alias
+ # we make, theres workarounds but it starts to get really crazy (its crazy enough
+ # the SQL that gets generated) so just require an alias
+ raise TypeError("Mapping against a Select object requires that it has a name. Use an alias to give it a name, i.e. s = select(...).alias('myselect')")
else:
self.table = table
+
+ if inherits is not None:
+ self.primarytable = inherits.primarytable
+ # inherit_condition is optional since the join can figure it out
+ self.table = sql.join(table, inherits.table, inherit_condition)
+ else:
+ self.primarytable = self.table
# locate all tables contained within the "table" passed in, which
# may be a join or other construct
self.table.accept_visitor(tf)
self.tables = tf.tables
- # determine "primary" table
- if primarytable is None:
- if len(self.tables) > 1:
- raise "table contains multiple tables - specify primary table argument to Mapper"
- self.primarytable = self.tables[0]
- else:
- self.primarytable = primarytable
# determine primary key columns, either passed in, or get them from our set of tables
self.pks_by_table = {}
except KeyError:
l = self.pks_by_table.setdefault(t, util.HashSet(ordered=True))
if not len(t.primary_key):
- raise "Table " + t.name + " has no primary key columns. Specify primary_key argument to mapper."
+ raise ValueError("Table " + t.name + " has no primary key columns. Specify primary_key argument to mapper.")
for k in t.primary_key:
l.append(k)
if properties is not None:
for key, prop in properties.iteritems():
if sql.is_column(prop):
+ try:
+ prop = self.table._get_col_by_original(prop)
+ except KeyError:
+ raise ValueError("Column '%s' is not represented in mapper's table" % prop._label)
self.columns[key] = prop
prop = ColumnProperty(prop)
elif isinstance(prop, list) and sql.is_column(prop[0]):
+ try:
+ prop = [self.table._get_col_by_original(p) for p in prop]
+ except KeyError, e:
+ raise ValueError("Column '%s' is not represented in mapper's table" % e.args[0])
self.columns[key] = prop[0]
prop = ColumnProperty(*prop)
self.props[key] = prop
proplist.append(prop)
self._get_clause = sql.and_()
- for primary_key in self.pks_by_table[self.primarytable]:
+ for primary_key in self.pks_by_table[self.table]:
self._get_clause.clauses.append(primary_key == sql.bindparam("pk_"+primary_key.key))
if (
return [result] + otherresults
else:
return result
-
+
def get(self, *ident):
"""returns an instance of the object based on the given identifier, or None
if not found. The *ident argument is a
list of primary key columns in the order of the table def's primary key columns."""
key = objectstore.get_id_key(ident, self.class_, self.primarytable)
#print "key: " + repr(key) + " ident: " + repr(ident)
+ return self._get(key, ident)
+
+ def _get(self, key, ident=None):
try:
return objectstore.uow()._get(key)
except KeyError:
+ if ident is None:
+ ident = key[2]
i = 0
params = {}
for primary_key in self.pks_by_table[self.primarytable]:
params["pk_"+primary_key.key] = ident[i]
i += 1
- print str(self._get_clause)
try:
return self.select(self._get_clause, params=params)[0]
except IndexError:
def _copy(self):
return DeferredColumnProperty(*self.columns)
+ def init(self, key, parent):
+ self.key = key
+ self.parent = parent
+ # establish a SmartProperty property manager on the object for this key,
+ # containing a callable to load in the attribute
+ if parent._is_primary_mapper():
+ objectstore.uow().register_attribute(parent.class_, key, uselist=False, callable_=lambda i:self.setup_loader(i))
+
def setup_loader(self, instance):
def lazyload():
clause = sql.and_()
- for primary_key in self.parent.pks_by_table[self.parent.primarytable]:
+ try:
+ pk = self.parent.pks_by_table[self.columns[0].table]
+ except KeyError:
+ pk = self.columns[0].table.primary_key
+ for primary_key in pk:
attr = self.parent._getattrbycolumn(instance, primary_key)
if not attr:
return None
def setup(self, key, statement, **options):
pass
-
- def init(self, key, parent):
- self.key = key
- self.parent = parent
- # establish a SmartProperty property manager on the object for this key,
- # containing a callable to load in the attribute
- if parent._is_primary_mapper():
- objectstore.uow().register_attribute(parent.class_, key, uselist=False, callable_=lambda i:self.setup_loader(i))
def execute(self, instance, row, identitykey, imap, isnew):
if isnew:
objectstore.uow().register_attribute(class_, key, uselist = self.uselist, deleteremoved = self.private, extension=self.attributeext)
def _get_direction(self):
- if self.parent.primarytable is self.target:
+# print self.key, repr(self.parent.table.name), repr(self.parent.primarytable.name), repr(self.foreignkey.table.name)
+ if self.parent.table is self.target:
if self.foreignkey.primary_key:
return PropertyLoader.RIGHT
else:
return PropertyLoader.CENTER
elif self.foreignkey.table == self.target:
return PropertyLoader.LEFT
- elif self.foreignkey.table == self.parent.primarytable:
+ elif self.foreignkey.table == self.parent.table:
return PropertyLoader.RIGHT
else:
raise "Cant determine relation direction"
self.primaryjoin.accept_visitor(processor)
if self.secondaryjoin is not None:
self.secondaryjoin.accept_visitor(processor)
-
+ if len(self.syncrules) == 0:
+ raise "No syncrules generated for join criterion " + str(self.primaryjoin)
+
def get_criterion(self, key, value):
"""given a key/value pair, determines if this PropertyLoader's mapper contains a key of the
given name in its property list, or if this PropertyLoader's association mapper, if any,
if self.association is not None:
# association object. our mapper should be dependent on both
# the parent mapper and the association object mapper.
-
- # this seems to work, association->parent->self, then
- # we process the child elements after the 'parent' save. but
- # then the parent is dependent on the association which is
- # somewhat arbitrary, might compete with some other dependency:
- # uowcommit.register_dependency(self.association, self.parent)
- # uowcommit.register_dependency(self.parent, self.mapper)
- # #uowcommit.register_dependency(self.association, self.mapper)
- # uowcommit.register_processor(self.parent, self, self.parent, False)
- # uowcommit.register_processor(self.parent, self, self.parent, True)
-
# this is where we put the "stub" as a marker, so we get
# association/parent->stub->self, then we process the child
# elments after the 'stub' save, which is before our own
# to possibly save a DB round trip
if self.use_get:
ident = []
- for primary_key in self.mapper.pks_by_table[self.mapper.primarytable]:
- ident.append(params[self.mapper.primarytable.name + "_" + primary_key.key])
+ for primary_key in self.mapper.pks_by_table[self.mapper.table]:
+ ident.append(params[self.mapper.table.name + "_" + primary_key.key])
return self.mapper.get(*ident)
elif self.order_by is not False:
order_by = self.order_by
if self.secondaryjoin is not None:
[self.to_alias.append(f) for f in self.secondaryjoin._get_from_objects()]
try:
- del self.to_alias[parent.primarytable]
+# del self.to_alias[parent.primarytable]
+ del self.to_alias[parent.table]
except KeyError:
pass