2011-03-22 30 views
1

我正在嘗試使用Sql Alchemy來製作一些通用的應用程序,例如任何模型的標籤或評級。但我在文檔中找不到任何幫助。我真的很喜歡我能用django contenttypes框架做些什麼? Sql Alchemy中是否有類似的功能?與django contenttypes中的sqlalchemy的通用關係

回答

3

我曾經寫過一些關於類似的例子代碼(見http://taketwoprogramming.blogspot.com/2009/08/reusable-sqlalchemy-models.html)。

的基本想法是,你可以創建這樣一個模型:

@commentable 
class Post(Base): 
    __tablename__ = 'posts' 
    id = sa.Column(sa.Integer, primary_key=True) 
    text = sa.Column(sa.String) 

...其中commentable這樣定義...

class BaseComment(object): 
    pass 

def build_comment_model(clazz): 
    class_table_name = str(class_mapper(clazz).local_table) 
    metadata = clazz.metadata 

    comment_class_name = clazz.__name__ + 'Comment' 
    comment_class = type(comment_class_name, (BaseComment,), {}) 

    comment_table_name = class_table_name + '_comments' 
    comment_table = sa.Table(comment_table_name, metadata, 
     sa.Column('id', sa.Integer, primary_key=True), 
     sa.Column(class_table_name + '_id', 
      sa.Integer, 
      sa.ForeignKey(class_table_name + '.id')), 

     sa.Column('text', sa.String), 
     sa.Column('name', sa.String(100)), 
     sa.Column('url', sa.String(255)), 
    ) 

    mapper(comment_class, comment_table) 

    return comment_class, comment_table 

def commentable(clazz): 
    comment_class, comment_table = build_comment_model(clazz) 

    clazz.Comment = comment_class 
    setattr(clazz, 'comments', relation(comment_class)) 

    def add_comment(self, comment): 
     self.comments.append(comment) 

    setattr(clazz, 'add_comment', add_comment) 

    return clazz 

基本上,commentable裝飾動態創建一個新的類型和表格,以及一些輔助方法的裝飾類。這是我用來測試的代碼工作,這說明它是如何工作的一些例子測試...

class TestModels(SATestCase): 
    def test_make_comment(self): 
     p = Post() 
     p.text = 'SQLAlchemy is amazing!' 

     text = 'I agree!' 
     name = 'Mark' 
     url = 'http://www.sqlalchemy.org/' 

     c = Post.Comment() 
     c.text = text 
     c.name = name 
     c.url = url 
     p.add_comment(c) 
     Session.add(p) 

     # This is a method I use to force the reload of the objects from 
     # the database to make sure that when I test them, I'm actually 
     # pulling from the database rather than just getting the data 
     # of the object still in the session. 
     p = self.reload(p) 

     self.assertEquals(len(p.comments), 1) 
     c = p.comments[0] 
     self.assertEquals(c.text, text) 
     self.assertEquals(c.name, name) 
     self.assertEquals(c.url, url) 

我前一段時間寫了這個,但我不認爲有在SQLA任何會爲你做這種事情,但你可以創造類似的東西,沒有太多的麻煩。在我的例子中,我創建了新的映射類和方法,以便在類裝飾器中實時使用它。

我從來沒有真正使用過它,但它可能會給你一些想法。