A few days ago I asked what appears in the body of the message, a few lines below. To summarize:
Let's say I have a class "User" (yeah, to define "users" in my application) and each user can belong to one "UserGroup" (another class of my application). The User class would be something like: class User(declarativeBase): """Represents a user""" __tablename__ = "users" _id = Column("id", Integer, primary_key=True) _firstName = Column("first_name", String(50)) _lastName = Column("last_name", String(50)) _userName = Column("user_name", String(50), unique=True, nullable=False) _password = Column("password", String(64), nullable=False) _userGroupId = Column("user_group_id", Integer, ForeignKey("user_groups.id")) _userGroup = relationship("UserGroup", uselist=False) id = synonym('_id', descriptor=property(getId, setId)) firstName = synonym('_firstName', descriptor=property(getFirstName, setFirstName)) lastName = synonym('_lastName', descriptor=property(getLastName, setLastName)) userName = synonym('_userName', descriptor=property(getUserName, setUserName)) password = synonym('_password', descriptor=property(getPassword, setPassword)) userGroupId = synonym('_userGroupId', descriptor=property(getUserGroupId, setUserGroupId)) userGroup = synonym('_userGroup', descriptor=property(getUserGroup, setUserGroup)) I wanted to find a way to find which synonyms "pointed" to foreign keys and which ones pointed to relationships. Basically, having a couple of methods like the following: def getRelationships(cls): that when invoked with getRelationships(User.User) would return a list with ["userGroup"] (withouth the "_" in front) and another: def getForeignKeys(cls): that would return ["userGroupId"] So far I've done this: def getRelationships(cls): retval = list() mapper = sqlalchemy.orm.class_mapper(cls) actualNameToSynonym = dict() relationships = set() for prop in mapper.iterate_properties: if isinstance(prop, sqlalchemy.orm.properties.SynonymProperty): actualNameToSynonym[prop.name] = prop.key # dictionary <_userName, userName, userGroup, _userGroup> elif isinstance(prop, sqlalchemy.orm.properties.RelationshipProperty): relationships.add(prop.key) #set with _userGroup, and rest of relationships for relationship in relationships: retval.append(actualNameToSynonym[relationship]) return retval def getForeignKeys(cls): retval = list() mapper = sqlalchemy.orm.class_mapper(cls) actualNameToSynonym = dict() columnsWithForeignKeys = set() for prop in mapper.iterate_properties: if isinstance(prop, sqlalchemy.orm.properties.SynonymProperty): actualNameToSynonym[prop.name] = prop.key # dictionary <_userName, userName, userGroup, _userGroup> elif isinstance(prop, sqlalchemy.orm.properties.ColumnProperty): for column in prop.columns: if len(column.foreign_keys) > 0: columnsWithForeignKeys.add(prop.key) for columnWithForeignKeys in columnsWithForeignKeys: retval.append(actualNameToSynonym[columnWithForeignKeys]) return retval Both are very similar: First they create a dictionary mapping the synonym's key with the "real" name (<_userGroup, userGroup>) and store the "relationships" or the columns that have a "foreign key" in a set (for the method that tries to get relationships, that set would be set("_userGroup") and for the one that tries to get foreign keys, set("_userGroupId")) . In a second "for" loop they match that "underscored" name with the name of the synonym to return a list with the names of the synonyms, and not the actual columns (basically, to transform "_userGroupId" to "userGroupId") They seem to work, at least with my not-complicated-at-all classes, but I'd like to know what do you guys think of my approach. Is it good? Can it break something? Is there a better way? Thank you! 2011/2/18 Hector Blanco <white.li...@gmail.com>: > I'll give it a try!! > > Thank you! > > 2011/2/18 Michael Bayer <mike...@zzzcomputing.com>: >> >> On Feb 17, 2011, at 6:37 PM, Hector Blanco wrote: >> >>> Hello everyone! >>> >>> Let's say I have a class defined like this: >>> >>> class User(declarativeBase): >>> """Represents a user""" >>> __tablename__ = "users" >>> >>> _id = Column("id", Integer, primary_key=True) >>> _phone = Column("phone", String(16)) >>> _userName = Column("user_name", String(50), unique=True, >>> nullable=False) >>> _password = Column("password", String(64), nullable=False) >>> >>> _userGroupId = Column("user_group_id", Integer, >>> ForeignKey("user_groups.id")) >>> _userGroup = relationship("UserGroup", uselist=False) >>> >>> def setId(self, id): >>> """Set id""" >>> self._id = int(id) >>> >>> def getId(self): >>> """Get id""" >>> return self._id >>> >>> def setUserGroupById(self, userGroupId): >>> userGroupId = int(userGroupId) >>> if userGroupId != self.userGroupId: >>> self.userGroup = UserGroupManager.getById(userGroupId) >>> >>> def setUserGroup(self, userGroup): >>> """Set user group""" >>> if isinstance(userGroup, UserGroup): >>> self._userGroup = userGroup >>> else: >>> raise TypeError("Trying to set a " + >>> str(type(userGroup)) + " as user group") >>> >>> def getUserGroup(self): >>> """Get user""" >>> return self._userGroup >>> >>> #More getters/setters >>> >>> id = sqlalchemy.orm.synonym('_id', descriptor=property(getId, setId)) >>> phone = sqlalchemy.orm.synonym('_phone', >>> descriptor=property(getPhone, setPhone)) >>> userName = sqlalchemy.orm.synonym('_userName', >>> descriptor=property(getUserName, setUserName)) >>> password = sqlalchemy.orm.synonym('_password', >>> descriptor=property(getPassword, setPassword)) >>> userGroupId = sqlalchemy.orm.synonym('_userGroupId', >>> descriptor=property(getUserGroup, setUserGroup)) >>> userGroup = sqlalchemy.orm.synonym('_userGroup', >>> descriptor=property(getUserGroup, setUserGroup)) >>> >>> I have created an utility that, given an instance gives me the names >>> of the synonyms in said instance. >>> >>> def getProperties(instance): >>> properties = list() >>> mapper = sqlalchemy.orm.object_mapper(instance) >>> for prop in mapper.iterate_properties: >>> if isinstance(prop, >>> sqlalchemy.orm.properties.SynonymProperty): >>> properties.append(prop.key) >>> return properties >>> >>> That would give me ["id", "phone", "userName", "password", >>> "userGroupId", "userGroup"], so I can more or less generically go >>> through all said values and execute things like >>> >>> for attribute in getProperties(instanceOfUser): >>> value = getattr(instanceOfUser, attribute) >>> >>> Is there any way of knowing that said "value"s are ForeignKeys or >>> relationships? For instance, I'd like to know that the attribute "id" >>> is a regular (well... kind of regular... it's a Primary key, but it's >>> not going to point to anything in another table) numeric attribute, >>> but "userGroupId" is a foreign key and "userGroup" is a Relationship. >>> I've been sneaking in the vars, __dict__, dir of the values returned >>> by getattr, but I haven't been able to find anything suitable. >> >> >> you just have to poke around and use isinstance() on the MapperProperty >> objects, and/or check for known attributes. The choices are >> ColumnProperty, RelationshipProperty, SynonymProperty, etc. >> >> synonyms are also superceded in 0.7. they're not very useful compared to >> hybrids. >> >> >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "sqlalchemy" group. >> To post to this group, send email to sqlalchemy@googlegroups.com. >> To unsubscribe from this group, send email to >> sqlalchemy+unsubscr...@googlegroups.com. >> For more options, visit this group at >> http://groups.google.com/group/sqlalchemy?hl=en. >> >> > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.