Реализация мощности IS-A в схемах Flask SQLAlchemy и Marshamllow. ⇐ Python
-
Anonymous
Реализация мощности IS-A в схемах Flask SQLAlchemy и Marshamllow.
Предположим, у меня есть таблица под названием User, которая содержит общую информацию обо всех пользователях, зарегистрированных в системе:
класс User(db.Model): __tablename__ = 'Пользователь' id = db.Column(db.Integer, Primary_key=True) роль = db.Column(db.String(20), nullable=False) электронная почта = db.Column(db.String(256), unique=True, nullable=False) пароль = db.Column(db.String(256), nullable=False) Sign_up_date = db.Column(db.DateTime, nullable=False) заархивировано = db.Column(db.Integer, nullable=False, по умолчанию=0) Тогда у меня есть два подтипа пользователей, каждый из которых содержит все вышеперечисленные столбцы, а также некоторые столбцы определенного типа. Например:
Клиент класса:
класс Клиент(Пользователь): __tablename__ = "Клиент" # ПОЛЬЗОВАТЕЛЬ — КЛИЕНТ адрес = db.Column(db.String(256), nullable=False) имя = db.Column(db.String(64), nullable=False) Драйвер класса:
класс Драйвер(Пользователь): __tablename__ = "Драйвер" # ПОЛЬЗОВАТЕЛЬ — ВОДИТЕЛЬ first_name = db.Column(db.String(64), nullable=False) Last_name = db.Column(db.String(64), nullable=False) Profile_picture_path = db.Column(db.String(256), nullable=False) Менеджер хранилищ классов:
класс WarehouseManager(User): __tablename__ = "Менеджер склада" # ПОЛЬЗОВАТЕЛЬ – МЕНЕДЖЕР СКЛАДОВ. first_name = db.Column(db.String(64), nullable=False) Last_name = db.Column(db.String(64), nullable=False) Profile_picture_path = db.Column(db.String(256), nullable=False) имя_хранилища = db.Column(db.String(64), nullable=False) и так далее.
Проблема возникает всякий раз, когда я пытаюсь создать это с помощью db.create_all(), я получаю следующую ошибку:
sqlalchemy.exc.ArgumentError: столбец «first_name» в классе WarehouseManager конфликтует с существующим столбцом «User.first_name». При использовании декларативного метода рассмотрите возможность использования параметра use_existing_column функции mapped_column() для разрешения конфликтов. Кроме того, я понятия не имею, как мне создавать для этого схемы в Marshmallow.
Для ясности: я хочу, чтобы база данных для Драйвера содержала user_id и все дополнительные поля (first_name, Last_name, Profile_picture_path), но когда я взаимодействую с базой данных через SQLAlchemy, я хочу иметь возможность вводить столбцы Пользователь в таблице Driver I.E.:
driver = Driver(email="driver@gmail.com", first_name="Имя драйвера"...) вместо:
user = Пользователи(email="driver@gmail.com"...) driver = Driver(user_id = user.id, first_name="Имя драйвера"...) Я считаю лестницу повторяющейся и плохой практикой с точки зрения использования качественного ORM. Качественный ORM должен легко справляться с этими распространенными случаями. Это не первый раз, когда я разочаровываюсь ограниченными возможностями ORM, особенно при работе с временными таблицами, материализованными представлениями, триггерами и так далее.
Изменить: Я попытался добавить use_existing_column в db.Column для first_name и last_name. У меня все еще та же ошибка.
Редактирование 2: Вот песочница, воспроизводящая проблему.
Предположим, у меня есть таблица под названием User, которая содержит общую информацию обо всех пользователях, зарегистрированных в системе:
класс User(db.Model): __tablename__ = 'Пользователь' id = db.Column(db.Integer, Primary_key=True) роль = db.Column(db.String(20), nullable=False) электронная почта = db.Column(db.String(256), unique=True, nullable=False) пароль = db.Column(db.String(256), nullable=False) Sign_up_date = db.Column(db.DateTime, nullable=False) заархивировано = db.Column(db.Integer, nullable=False, по умолчанию=0) Тогда у меня есть два подтипа пользователей, каждый из которых содержит все вышеперечисленные столбцы, а также некоторые столбцы определенного типа. Например:
Клиент класса:
класс Клиент(Пользователь): __tablename__ = "Клиент" # ПОЛЬЗОВАТЕЛЬ — КЛИЕНТ адрес = db.Column(db.String(256), nullable=False) имя = db.Column(db.String(64), nullable=False) Драйвер класса:
класс Драйвер(Пользователь): __tablename__ = "Драйвер" # ПОЛЬЗОВАТЕЛЬ — ВОДИТЕЛЬ first_name = db.Column(db.String(64), nullable=False) Last_name = db.Column(db.String(64), nullable=False) Profile_picture_path = db.Column(db.String(256), nullable=False) Менеджер хранилищ классов:
класс WarehouseManager(User): __tablename__ = "Менеджер склада" # ПОЛЬЗОВАТЕЛЬ – МЕНЕДЖЕР СКЛАДОВ. first_name = db.Column(db.String(64), nullable=False) Last_name = db.Column(db.String(64), nullable=False) Profile_picture_path = db.Column(db.String(256), nullable=False) имя_хранилища = db.Column(db.String(64), nullable=False) и так далее.
Проблема возникает всякий раз, когда я пытаюсь создать это с помощью db.create_all(), я получаю следующую ошибку:
sqlalchemy.exc.ArgumentError: столбец «first_name» в классе WarehouseManager конфликтует с существующим столбцом «User.first_name». При использовании декларативного метода рассмотрите возможность использования параметра use_existing_column функции mapped_column() для разрешения конфликтов. Кроме того, я понятия не имею, как мне создавать для этого схемы в Marshmallow.
Для ясности: я хочу, чтобы база данных для Драйвера содержала user_id и все дополнительные поля (first_name, Last_name, Profile_picture_path), но когда я взаимодействую с базой данных через SQLAlchemy, я хочу иметь возможность вводить столбцы Пользователь в таблице Driver I.E.:
driver = Driver(email="driver@gmail.com", first_name="Имя драйвера"...) вместо:
user = Пользователи(email="driver@gmail.com"...) driver = Driver(user_id = user.id, first_name="Имя драйвера"...) Я считаю лестницу повторяющейся и плохой практикой с точки зрения использования качественного ORM. Качественный ORM должен легко справляться с этими распространенными случаями. Это не первый раз, когда я разочаровываюсь ограниченными возможностями ORM, особенно при работе с временными таблицами, материализованными представлениями, триггерами и так далее.
Изменить: Я попытался добавить use_existing_column в db.Column для first_name и last_name. У меня все еще та же ошибка.
Редактирование 2: Вот песочница, воспроизводящая проблему.
Мобильная версия