Mixin добавляется в каждую таблицу дочерних классов при использовании наследования объединенной таблицы - PullRequest
0 голосов
/ 06 октября 2011

У меня есть следующие настройки:

class Attribute(object):
    a = Column(Integer)

class Thing(Base, Attribute):
    b = Column(Integer)

class Subthing(Thing):
    c = COlumn(Integer)

Однако и Thing, и Subthing будут иметь миксин Attribute, то есть оба будут иметь столбцы, указанные в Attribute:

Thing: a | b
Subthing: a | c

Мне нужны только эти столбцы миксина в Thing, а не Subthing:

Thing: a | b
Subthing: c

Возможно ли это, или мне придется прибегнуть к созданию столбцов и методов вручную вместо использования миксина для каждого Thing?

Ответы [ 3 ]

4 голосов
/ 06 октября 2011

Subthing получает a от родителя по определению наследования. Если вы не хотите такого поведения, Subthing не может наследовать от этого объекта. Возможное решение - ввести еще один базовый класс.

class Attribute(object):
    @declared_attr # the actual syntax on SQLAlchemy for doing mixins
    def a(cls):
       return Column(Integer)

class BaseThing(Base):
    pass

class Thing(BaseThing, Attribute):
    b = Column(Integer)

class Subthing(BaseThing):
    c = Column(Integer)

Тогда Subthing имеет только столбец c, а Thing имеет a и b.

1 голос
/ 15 сентября 2012

Это поведенческая несогласованность, возникшая в результате поведения @declared_attr, медленно отклоняющегося от поведенческого контракта, который был протестирован только в сценарии использования «копирование столбца».Первоначальный вариант использования «column on mixin» заключался в том, чтобы применять его ко всем наследуемым классам одинаково, однако @declared_attr, который был разработан чуть позже, не применил это поведение, а следовательно, и противоречиво.Копия столбца "вступить в силу только для не подкласса" - это несовместимое с поведением изменение, несовместимое с прошлым, так же как и в предстоящих 0.8.Это билет № 2565 (http://www.sqlalchemy.org/trac/ticket/2565)) и разрешен в r9baa197f2c67.

test:

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr

Base = declarative_base()

class Mixin(object):
    a = Column(Integer)

    @declared_attr
    def b(cls):
        return Column(Integer)

class A(Mixin, Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)

class B(A):
    __tablename__ = 'b'
    id = Column(Integer, ForeignKey('a.id'), primary_key=True)

assert 'a' in A.__table__.c
assert 'b' in A.__table__.c
assert 'a' not in B.__table__.c
assert 'b' not in B.__table__.c
0 голосов
/ 14 сентября 2012

Я просто столкнулся с той же проблемой.Оказывается, если вы определяете столбцы в своем классе mixin, используя @declared_attr, SQLAlchemy ведет себя правильно.Столбцы, объявленные непосредственно в mixin, попадают в подклассы при использовании наследования объединенных таблиц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...