2012-11-05 29 views
1

獲取關係元數據我有一個非常簡單的用戶類定義:從SQLAlchemy的

class User(Base): 
    implements(interfaces.IUser) 
    __tablename__ = 'users' 
    #Fields description 
    id = Column(Integer, primary_key=True) 

    client_id = Column(Integer, ForeignKey('w2_client.id')) 
    client = relationship("Client", backref=backref('users', order_by=id)) 

我想自動生成GUI編輯的對象的用戶(和其他類型的類)。所以,我需要獲得表的所有元數據,例如,我可以這樣做:

for c in User.__table__.columns: 
     print c.name, c.type, c.nullable, c.primary_key, c.foreign_keys 

但我不能得到有關的關係「客戶端」的任何信息,該c.foreign_keys只顯示我的表與foreign_keys有關,但不是我定義的屬性「client」。 請讓我知道如果我的問題不明確

回答

2

確實不容易獲得。經過一些逆向工程後,我不得不提出自己的功能。

這是我使用的元數據。我和你正在尋找的東西有點不同,但也許你可以使用它。

# structure returned by get_metadata function. 
MetaDataTuple = collections.namedtuple("MetaDataTuple", 
     "coltype, colname, default, m2m, nullable, uselist, collection") 


def get_metadata_iterator(class_): 
    for prop in class_mapper(class_).iterate_properties: 
     name = prop.key 
     if name.startswith("_") or name == "id" or name.endswith("_id"): 
      continue 
     md = _get_column_metadata(prop) 
     if md is None: 
      continue 
     yield md 


def get_column_metadata(class_, colname): 
    prop = class_mapper(class_).get_property(colname) 
    md = _get_column_metadata(prop) 
    if md is None: 
     raise ValueError("Not a column name: %r." % (colname,)) 
    return md 


def _get_column_metadata(prop): 
    name = prop.key 
    m2m = False 
    default = None 
    nullable = None 
    uselist = False 
    collection = None 
    proptype = type(prop) 
    if proptype is ColumnProperty: 
     coltype = type(prop.columns[0].type).__name__ 
     try: 
      default = prop.columns[0].default 
     except AttributeError: 
      default = None 
     else: 
      if default is not None: 
       default = default.arg(None) 
     nullable = prop.columns[0].nullable 
    elif proptype is RelationshipProperty: 
     coltype = RelationshipProperty.__name__ 
     m2m = prop.secondary is not None 
     nullable = prop.local_side[0].nullable 
     uselist = prop.uselist 
     if prop.collection_class is not None: 
      collection = type(prop.collection_class()).__name__ 
     else: 
      collection = "list" 
    else: 
     return None 
    return MetaDataTuple(coltype, str(name), default, m2m, nullable, uselist, collection) 


def get_metadata(class_): 
    """Returns a list of MetaDataTuple structures. 
    """ 
    return list(get_metadata_iterator(class_)) 


def get_metadata_map(class_): 
    rv = {} 
    for metadata in get_metadata_iterator(class_): 
     rv[metadata.colname] = metadata 
    return rv 

但它沒有主鍵。我爲此使用了一個單獨的函數。

mapper = class_mapper(ORMClass) 
pkname = str(mapper.primary_key[0].name) 

也許我應該把主鍵名稱放在元數據中。

+0

您剛剛確認沒有乾淨的方式來做到這一點。我現在的解決方案是使用一個字典來定義我需要的所有信息。感謝您的支持! – nam