def __init__(self, child_class, child_key=None, foreign_key=None, column=None, title=None, has_default=None, cache=True): """ @param cache: Indicates whether the relationship object shall keep a copy of the child object in the dbobj for faster access. """ if foreign_key is not None and column is not None: raise Exception("You can't specify both a foreign_key (based"+\ " on attribute names) and an SQL column for "+\ " a many2one relationship") datatype.__init__(self, column, title, (), has_default) if foreign_key is None: pk = keys.primary_key(child_class) self.python_class = pk.attribute().python_class self.sql_literal_class = pk.attribute().sql_literal_class self.child_class = child_class if child_key is None: self.child_key = child_class.__primary_key__ else: self.child_key = child_key self.foreign_key = foreign_key self.cache = cache
def all(self, *clauses): """ This method will return all entries in the child relation (or a subset specified by clauses) and a list of those primary keys which are present in the link table. You can check if a dbobj is linked by doing: >>> result, active_keys = dbobj.relation.all() >>> for a in result: ... if a.__primary_key__.values() in active_keys: ... do_something(a) ... else: ... do_somethin_else(a) """ if self.dbobj.__is_stored__(): relations = ( self.relationship.link_relation, self.child_class().__view__, ) join_clauses = self.add_where(clauses) child_pkey = keys.primary_key(self.child_class()) query = sql.select( tuple(child_pkey.columns()), relations, *join_clauses) cursor = self.ds().execute(query) active_keys = list(cursor.fetchall()) else: active_keys = [] result = self.ds().select(self.child_class(), *clauses) return ( result, active_keys, )
def select_for_update(self, dbclass, key): """ This method works like L{select_by_primary_key} above, except that it doesn't select anything but returns a dummy object (an empty dbobj) that will allow setting attributes, yielding proper UPDATE statements. Note that supplying a primary key that does not exist will go unnoticed: The UPDATE statements won't create an error, they just won't affect any rows. This method is primarily ment for transaction based (i.e. www) applications. """ if type(key) != TupleType: key = ( key, ) primary_key = keys.primary_key(dbclass) if len(key) != len(primary_key.key_attributes): msg = "The primary key for %s must have %i elements." % \ ( repr(dbclass), len(primary_key.key_attributes), ) raise IllegalPrimaryKey(msg) info = stupid_dict() for property, value in zip(primary_key.attributes(), key): info[property.column] = value return dbclass.__from_result__(self, info)
def primary_key_where(self, dbclass, key): """ Return a t4.orm.sql where clause that will yield the object of dbclass whoes primary key equals key @param dbclass: The dbclass of the object the where clause is supposed to be for. @param key: Python value representing the primary key or a tuple of such Python values, if the primary key has multiple columns """ # this function is very simmilar to keys.key.where() - maybe unify? if type(key) != TupleType: key = ( key, ) primary_key = keys.primary_key(dbclass) if len(key) != len(primary_key.key_attributes): msg = "The primary key for %s must have %i elements." % \ ( repr(dbclass), len(primary_key.key_attributes), ) raise IllegalPrimaryKey(msg) where = [] for property, value in zip(primary_key.attributes(), key): literal = property.sql_literal_class(property.__convert__(value)) where.append(property.column) where.append("=") where.append(literal) where.append("AND") del where[-1] # remove last "AND" return sql.where(*where)
def __init__(self, **kw): """ Construct a dbobj from key word arguments. Example:: me = person(firstname='Diedrich', lastname='Vorberg') firstname and lastname are dbproperties. The reserved parameter __ds allows you to pass a datasource to objects that are not inserted yet and might need a ds to construct stuff. """ self.__changed_columns__ = {} if kw.has_key("__ds"): __ds = kw["__ds"] del kw["__ds"] if not isinstance(__ds, datasource_base): raise TypeError("__ds must be a subclass of " + "orm2.datasource.datasource_base") else: __ds = None self._ds = __ds self._is_stored = False for name, prop in self.__class__.__dict__.iteritems(): if isinstance(prop, datatype) and not hasattr(prop, "dbclass"): prop.__init_dbclass__(self.__class__, name) self.__update_from_dict__(kw) if self.__primary_key__ == (): self.__primary_key__ = None if self.__primary_key__ is not None: self.__primary_key__ = keys.primary_key(self)