Самоссылающаяся таблица SQLAlchemy не может иметь 0 в качестве основного индекса?

Я столкнулся с очень странной проблемой с SQLAlchemy. У меня есть модель, которая ссылается на себя (связь списка смежности). Я просто скопировал модель (узел) из руководства по SQLAlchemy. Вот код модели:

class Node(Base):
    __tablename__ = 'nodes'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('nodes.id'))
    parent = Column(Unicode(50))

    children = relationship('Node',
        cascade="all", #tried to remove this
        backref=backref("parent", remote_side='Node.id'),
        collection_class=attribute_mapped_collection('data'), #tried to remove this as well
    )

Я воспроизвел проблему в своих контроллерах, но я также провел этот тест (конечно, после полной загрузки моей среды):

parent = Node()
parent.id = 1
parent.parent_id = None
parent.name = 'parent'
Session.add(parent)

child = Node()
child.id = 20
child.parent_id = 1
child.name = 'child'
Session.add(child)

Session.commit()

Приведенный выше код отлично работает (изменения успешно фиксируются и отражаются в БД).

Проблема возникает, когда я изменяю идентификатор узла parent на 0 (и соответственно parent_id узла child на 0). Затем я получаю следующее исключение:

......
File "C:\Python26\Lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
sqlalchemy.exc.IntegrityError: (IntegrityError) (1452, 'Cannot add or update a child row: a
foreign key constraint fails (`db`.`nodes`, CONSTRAINT `nodes_ibfk_1` FOREIGN KEY
(`parent_id`) REFERENCES `nodes` (`id`))') 'INSERT INTO nodes (id, parent_id, name) VALUES 
(%s, %s, %s)' (20, 0, 'child')

Удивительно, но изменение этого значения (идентификатор node и parent_id child) на любое, кроме 0 (-5, 1 и 150), устраняет ошибку.

Я упускаю что-то очевидное? Нельзя ли присвоить 0 столбцу Integer id, ссылающемуся на себя?

Спасибо!


person Raiders    schedule 20.04.2011    source источник
comment
Хорошо, некоторые исследования показали, что когда я вставляю значение 0 в качестве идентификатора, MySQL рассматривает мой столбец идентификатора как последовательность и продвигает его. Поэтому, если там ничего не было, он устанавливает его в 1. Если предыдущая строка была введена с идентификатором 6, вставка новой строки с идентификатором, если 0, приведет к тому, что новая строка будет иметь 7 в качестве своего идентификатора. Любая идея, почему это происходит и как обойти это??   -  person Raiders    schedule 20.04.2011
comment
По-видимому, все мои столбцы Column (Integer, primary_key = True) по умолчанию имеют значение AUTO_INCREMENT. Как отменить эту опцию по умолчанию (кроме явной передачи autoincrement=False?   -  person Raiders    schedule 20.04.2011


Ответы (1)


MySQL использует сгенерированные идентификаторы, когда вы явно передаете NULL или 0. Передайте autoincrement=False в качестве аргумента Column, чтобы отключить AUTO_INCREMENT.

person Denis Otkidach    schedule 20.04.2011