SQLAlchemy с несколькими первичными ключами не устанавливает автоматически - PullRequest
3 голосов
/ 10 марта 2010

У меня была простая таблица:

class test(Base):
    __tablename__ = 'test'
    id = Column(Integer, primary_key=True)
    title = Column(String)

    def __init__(self, title):
        self.title = title

При использовании этой таблицы идентификатор был установлен автоматически. Я хочу добавить другое поле, уникальное и эффективное для поиска, поэтому я добавил поле:

id2 = Column(String, primary_key=True)

И обновил конструктор:

def __init__(self, id2, title):
    self.id2 = id2
    self.title = title

Теперь идентификатор больше не устанавливается автоматически, или, скорее, я получаю ошибку:

IntegrityError: (IntegrityError) test.id не может быть равен NULL u'INSERT INTO test (id2, title) ЗНАЧЕНИЯ (?,?) '[U'a', u'b ']

Есть ли способ сохранить второй первичный ключ, не удаляя автоинкремент поведения первого?

1 Ответ

7 голосов
/ 10 марта 2010

У меня здесь мало проблем

1) Какова цель вашей ручной работы __init__? Если он выполняет только то, что вы написали, вы можете полностью опустить конструктор, поскольку механизм SQLAlchemy автоматически генерирует один и тот же конструктор для всех ваших моделей. Хотя, если вы предпримете некоторые дополнительные действия и, следовательно, должны переопределить __init__, вы, вероятно, захотите вызвать супер-конструктор:

def __init__(self, lalala, *args, **kwargs):
   # do something with lalala here...
   super(test, self).__init__(*args, **kwargs)
   # ...or here

2) Если у вас есть более одного поля с primary_key=True, вы получите модель с составным первичным ключом. Составные первичные ключи не генерируются автоматически, поскольку здесь есть неоднозначность: чем должен отличаться последующий ключ от предыдущего?

Я подозреваю, что то, что вы пытаетесь, может быть достигнуто с помощью уникального индексированного столбца и без использования составного ключа:

class test(Base):
    __tablename__ = 'test'
    id = Column(Integer, primary_key=True)
    id2 = Column(String, index=True, unique=True)
    title = Column(String)

    # def __init__(self) is not necessary
...