Я пытаюсь повторно использовать первичный ключ в одной из моих таблиц с SQLAlchemy и получаю ошибку ограничения внешнего ключа.
В двух словах:
У меня есть 3 таблицы: User, Inventories and Devices. У Inventory and Devices есть one- to- одно отношение с пользователем. User.id - это Inventories.user_id и Devices.user_id с внешней ключами.
У меня есть User, Devices и Inventories, настроенные в моделях/в соответствии со стандартными методами python.
Внутри интерактивного python я могу без проблем выполнить следующие команды:
>>>newUser = User.create()
>>>newUser.device = User.create_device(<*args>)
>>>Session.add(newUser)
>>>Session.commit()
(запись инвентаря автоматически создается в коде)
Теперь, скажем, я хочу, чтобы re- использовал запись пользователя 1 (это единственная запись, которая позволит использовать метод под названием reset в коде для обеспечения безопасности и внутренних тестов)
>>>oldUser = User.retrieve(1)
>>>Session.delete(oldUser)
>>>Session.commit()
(подтвердите, что пользователь 1 больше не существует)
>>>newUser = User.create()
>>>newUser.device = User.create_device(<*args>)
>>>newUser.id = 1
>>>Session.add(newUser)
>>>Session.commit()
В этот момент я либо получу eror, что Key (id) = (<id>
) по-прежнему ссылается на таблицы "устройства" (или "запасы" ), где <id>
является newUser.id до re- присваивая ему id 1
Я просмотрел каскадные и попробовал различные варианты (все, save- update и т.д.) без эффекта.
Любая информация, указывающая на то, где я ошибаюсь, будет очень оценена,
Спасибо,
Крыс
Так как это проблема, которая не должна рассматриваться в процессе производства, просто используйте SET CONSTRAINTS
. Вы можете использовать INITIALLY DEFERRED
на FOREIGN KEY
, но я бы не рекомендовал это, так как вы не имеете дело с циклической зависимостью, которая существует в производство.
Я не использую SQLAlchemy, поэтому у меня нет правильного ответа, но я могу сказать, что вы должны спросить себя, что вам нужно, действительно нужно?
Поскольку,
Итак, прежде всего, вы должны решить, стоит ли это?
Чтобы устранить ошибку, которую вы видите, вы можете обновить внешние ключи всех моделей Device
и Inventory
, связанных с этой моделью User
, прежде чем совершать. Вы должны убедиться, что ваша модель User
не auto- увеличивает идентификатор (т.е. Не является последовательностью PostgreSQL).
Например, объявление модели SQLAlchemy должно быть
class User(base):
__tablename__ = 'user'
id = Column('id', Integer, primary_key=True, unique=True, nullable=False)
вместо
class User(base):
__tablename__ = 'user'
id = Column('id', Integer, Sequence('user_id_seq'), primary_key=True)
НО, это, вероятно, не самый правильный способ сделать это! Было бы лучше использовать последовательность на User.id
(как во втором объявлении модели) и добавить другое поле в таблице пользователя, которое указывает, является ли пользователь администратором (для целей безопасности/тестирования, о которых вы упомянули). Таким образом, вам не нужно полагаться на магические числа в вашем приложении (например, идентификатор пользователя) для логики приложения, особенно безопасности.