diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2007-02-25 22:44:52 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2007-02-25 22:44:52 +0000 |
| commit | 962c22c9eda7d2ab7dc0b41bd1c7a52cf0c9d008 (patch) | |
| tree | f0ab113c7947c80dfea42d4a1bef52217bf6ed96 /lib/sqlalchemy/orm/sync.py | |
| parent | 8fa3becd5fac57bb898a0090bafaac377b60f070 (diff) | |
| download | sqlalchemy-962c22c9eda7d2ab7dc0b41bd1c7a52cf0c9d008.tar.gz | |
migrated (most) docstrings to pep-257 format, docstring generator using straight <pre> + trim() func
for now. applies most of [ticket:214], compliemnts of Lele Gaifax
Diffstat (limited to 'lib/sqlalchemy/orm/sync.py')
| -rw-r--r-- | lib/sqlalchemy/orm/sync.py | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/lib/sqlalchemy/orm/sync.py b/lib/sqlalchemy/orm/sync.py index 4b9b0c35c..68fa9cee1 100644 --- a/lib/sqlalchemy/orm/sync.py +++ b/lib/sqlalchemy/orm/sync.py @@ -10,21 +10,30 @@ from sqlalchemy import sql, schema, exceptions from sqlalchemy import logging from sqlalchemy.orm import util as mapperutil -"""contains the ClauseSynchronizer class, which is used to map attributes between two objects -in a manner corresponding to a SQL clause that compares column values.""" +"""Contains the ClauseSynchronizer class, which is used to map +attributes between two objects in a manner corresponding to a SQL +clause that compares column values. +""" ONETOMANY = 0 MANYTOONE = 1 MANYTOMANY = 2 class ClauseSynchronizer(object): - """Given a SQL clause, usually a series of one or more binary - expressions between columns, and a set of 'source' and 'destination' mappers, compiles a set of SyncRules - corresponding to that information. The ClauseSynchronizer can then be executed given a set of parent/child - objects or destination dictionary, which will iterate through each of its SyncRules and execute them. - Each SyncRule will copy the value of a single attribute from the parent - to the child, corresponding to the pair of columns in a particular binary expression, using the source and - destination mappers to map those two columns to object attributes within parent and child.""" + """Given a SQL clause, usually a series of one or more binary + expressions between columns, and a set of 'source' and + 'destination' mappers, compiles a set of SyncRules corresponding + to that information. + + The ClauseSynchronizer can then be executed given a set of + parent/child objects or destination dictionary, which will iterate + through each of its SyncRules and execute them. Each SyncRule + will copy the value of a single attribute from the parent to the + child, corresponding to the pair of columns in a particular binary + expression, using the source and destination mappers to map those + two columns to object attributes within parent and child. + """ + def __init__(self, parent_mapper, child_mapper, direction): self.parent_mapper = parent_mapper self.child_mapper = child_mapper @@ -33,17 +42,18 @@ class ClauseSynchronizer(object): def compile(self, sqlclause, foreign_keys=None, issecondary=None): def compile_binary(binary): - """assemble a SyncRule given a single binary condition""" + """Assemble a SyncRule given a single binary condition.""" + if binary.operator != '=' or not isinstance(binary.left, schema.Column) or not isinstance(binary.right, schema.Column): return source_column = None dest_column = None - + if foreign_keys is None: if binary.left.table == binary.right.table: raise exceptions.ArgumentError("need foreign_keys argument for self-referential sync") - + if binary.left in [f.column for f in binary.right.foreign_keys]: dest_column = binary.right source_column = binary.left @@ -57,8 +67,8 @@ class ClauseSynchronizer(object): elif binary.right in foreign_keys: source_column = binary.left dest_column = binary.right - - if source_column and dest_column: + + if source_column and dest_column: if self.direction == ONETOMANY: self.syncrules.append(SyncRule(self.parent_mapper, source_column, dest_column, dest_mapper=self.child_mapper)) elif self.direction == MANYTOONE: @@ -74,40 +84,45 @@ class ClauseSynchronizer(object): sqlclause.accept_visitor(processor) if len(self.syncrules) == rules_added: raise exceptions.ArgumentError("No syncrules generated for join criterion " + str(sqlclause)) - + def dest_columns(self): return [r.dest_column for r in self.syncrules if r.dest_column is not None] def execute(self, source, dest, obj=None, child=None, clearkeys=None): for rule in self.syncrules: rule.execute(source, dest, obj, child, clearkeys) - + class SyncRule(object): - """An instruction indicating how to populate the objects on each side of a relationship. - i.e. if table1 column A is joined against - table2 column B, and we are a one-to-many from table1 to table2, a syncrule would say - 'take the A attribute from object1 and assign it to the B attribute on object2'. - - A rule contains the source mapper, the source column, destination column, - destination mapper in the case of a one/many relationship, and - the integer direction of this mapper relative to the association in the case - of a many to many relationship. + """An instruction indicating how to populate the objects on each + side of a relationship. + + In other words, if table1 column A is joined against table2 column + B, and we are a one-to-many from table1 to table2, a syncrule + would say *take the A attribute from object1 and assign it to the + B attribute on object2*. + + A rule contains the source mapper, the source column, destination + column, destination mapper in the case of a one/many relationship, + and the integer direction of this mapper relative to the + association in the case of a many to many relationship. """ + def __init__(self, source_mapper, source_column, dest_column, dest_mapper=None, issecondary=None): self.source_mapper = source_mapper self.source_column = source_column self.issecondary = issecondary self.dest_mapper = dest_mapper self.dest_column = dest_column - + #print "SyncRule", source_mapper, source_column, dest_column, dest_mapper + def dest_primary_key(self): try: return self._dest_primary_key except AttributeError: self._dest_primary_key = self.dest_mapper is not None and self.dest_column in self.dest_mapper.pks_by_table[self.dest_column.table] return self._dest_primary_key - + def execute(self, source, dest, obj, child, clearkeys): if source is None: if self.issecondary is False: @@ -124,16 +139,16 @@ class SyncRule(object): else: if clearkeys and self.dest_primary_key(): raise exceptions.AssertionError("Dependency rule tried to blank-out primary key column '%s' on instance '%s'" % (str(self.dest_column), mapperutil.instance_str(dest))) - + if logging.is_debug_enabled(self.logger): self.logger.debug("execute() instances: %s(%s)->%s(%s) ('%s')" % (mapperutil.instance_str(source), str(self.source_column), mapperutil.instance_str(dest), str(self.dest_column), value)) self.dest_mapper.set_attr_by_column(dest, self.dest_column, value) SyncRule.logger = logging.class_logger(SyncRule) - + class BinaryVisitor(sql.ClauseVisitor): def __init__(self, func): self.func = func + def visit_binary(self, binary): self.func(binary) - |
