代码之家  ›  专栏  ›  技术社区  ›  max

SQLAlchemy:避免声明式样式类定义中的重复

  •  11
  • max  · 技术社区  · 14 年前

    我使用的是SQLAlchemy,对象模型中的许多类都具有相同的两个属性:id和(整数和主键)以及name(字符串)。我尽量避免在每个类中都这样声明它们:

    class C1(declarative_base()):
        id = Column(Integer, primary_key = True)
        name = Column(String)
        #...
    
    class C2(declarative_base()):
        id = Column(Integer, primary_key = True)
        name = Column(String)
        #...
    

    有什么好办法?我试着用元类,但还没用。

    3 回复  |  直到 14 年前
        1
  •  13
  •   dhaffey    8 年前

    mixin class declarative_base() :

    from sqlalchemy import Column, Integer, String
    from sqlalchemy.ext.declarative import declarative_base
    
    class IdNameMixin(object):
        id = Column(Integer, primary_key=True)
        name = Column(String)
    
    class C1(declarative_base(), IdNameMixin):
        __tablename__ = 'C1'
    
    class C2(declarative_base(), IdNameMixin):
        __tablename__ = 'C2'
    
    print C1.__dict__['id'] is C2.__dict__['id']
    print C1.__dict__['name'] is C2.__dict__['name']
    

    编辑 :您可能认为这会导致 C1 C2 共享相同的 Column 对象,但如 SQLAlchemy docs 复制 当源于mixin类时。我已经更新了代码示例来演示这种行为。

        2
  •  2
  •   jkmacc    13 年前

    你也可以用这个栏目的复制方法吗?这样,可以独立于表定义字段,而重用的字段只是字段.副本()-编辑。

    id = Column(Integer, primary_key = True)
    name = Column(String)
    
    class C1(declarative_base()):
        id = id.copy()
        name = name.copy()
        #...
    
    class C2(declarative_base()):
        id = id.copy()
        name = name.copy()
        #...
    
        3
  •  1
  •   max    14 年前

    我想我成功了。

    def __new__(mcs, name, base, attr):
      attr['__tablename__'] = name.lower()
      attr['id'] = Column(Integer, primary_key = True)
      attr['name'] = Column(String)
      return super().__new__(mcs, name, base, attr)
    

    而且看起来效果不错。