Как я могу установить sh связь с базой данных, которая позволяет различным типам пользователей регистрироваться в SqlAlchemy - PullRequest
0 голосов
/ 23 января 2020

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

Диаграмма базы данных

У меня есть отношение один к одному от "zpeedr <-> user" и то же самое для "merchant <-> user". Я использую flask_sqlalchemy с базой данных postgresql. Невозможно создать пользователя типа zpeedr или продавца, не связав его с существующим user.id, как предполагалось. Моя проблема в том, что с помощью этой настройки я могу назначить один и тот же user_id и для zpeedr, и для продавца. Как я могу убедиться, что один user.id может быть связан только с пользователем zpeedr или пользователем продавца?

Мой упрощенный код для создания таблицы:

</p>

<p>class User(UserMixin, db.Model):
    ''' User properties '''
    id = db.Column(db.Integer, primary_key=True)
    role = db.Column(db.String(10), nullable=False)
    name = db.Column(db.String(50), nullable=False)
    email = db.Column(db.String(50), unique=True, nullable=False)
    password_hash = db.Column(db.String(250), nullable=False)
    status = db.Column(db.String(15), server_default="Pending")
    registration_date = db.Column(db.DateTime, server_default=db.func.current_timestamp())
    zpeedr = db.relationship('Zpeedr', backref='user', uselist=False)
    merchant = db.relationship('Merchant', backref='user', uselist=False)</p>

<pre><code>def __init__(self, role, name, email, password_hash, status, registration_date, zpeedr, merchant):
    self.role = role
    self.name = name
    self.email = email
    self.password_hash = password_hash
    self.status = status
    self.registration_date = registration_date
    self.zpeedr = zpeedr
    self.merchant = merchant
</code>

class Zpeedr (db.Model): '' 'Свойства Zpeedr' '' id = db.Column (db.Integer, primary_key = True) # Внешний ключ таблицы пользователя user_id = db.Column (db.Integer, db.ForeignKey ('user .id '), nullable = False, уникальный = True) адрес = db.Column (db.String (200), nullable = False) location = db.Column (db.String (50), nullable = False) zipcode = db .Column (db.String (10), nullable = False) contact = db.Column (db.String (15), nullable = False) vat = db.Column (db.String (20), nullable = False, уникальное = True) nin = db.Column (db.String (20), nullable = False, unique = True)

def __init__(self, user_id, address, location, zipcode, contact, vat, nin):
    self.user_id = user_id
    self.address = address
    self.location = location
    self.zipcode = zipcode
    self.contact = contact
    self.vat = vat
    self.nin = nin

class Merchant (db.Model): '' 'Merchant Properties' '' id = db.Column (db.Integer, primary_key = True) # ForeignKey для таблицы пользователя user_id = db.Column (db.Integer, db.ForeignKey ('user.id'), nullable = False, unique = True) ticker = db. Столбец (db.String (4), nullable = False) y = db.Column (db.String (10), nullable = False) address = db.Column (db.String (200), nullable = False) location = db.Column (db.String (50), nullable = False ) zipcode = db.Column (db.String (10), nullable = False) contact = db.Column (db.String (15), nullable = False) vat = db.Column (db.String (20), nullable = False, unique = True) nin = db.Column (db.String (20), nullable = False, unique = True) # Establi sh отношение с таблицей Support_merchant (один ко многим) support_merchant = db.relationship (' Support_merchant ', backref =' merchant ')

def __init__(self, user_id, ticker, category, address, location, zipcode, contact, vat, nin): self.user_id = user_id self.ticker = ticker self.category = category self.address = address self.location = location self.zipcode = zipcode self.contact = contact self.vat = vat self.nin = nin

1 Ответ

0 голосов
/ 23 января 2020

Если целью пользователя таблицы является просто сохранение общих данных, вы можете использовать postgres наследование .

В очень упрощенной модели вы можете иметь: родительскую таблицу со всеми общими данными

create table user_(
  type varchar(1)
  );

и ваших детей:

 create table zeepdr(
   id integer primary key,
   nin varchar
   ) inherits(user_);

 create table merchant(
   id integer primary key,
   ticker char(4)
  ) inherits(user_);

Соответствующий код в SQLAlchemy должен выглядеть примерно так:

Table("zeepdr", metadata, ..., postgresql_inherits="user_")

Basi c Использование

Вставка

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

insert into zeepdr(id, type, nin) values(1,'Z','a');
insert into merchant(id, type, ticker) values(1,'M','aaaa');

Это также означает, что пользователь будет либо торговцем, либо zeepdr.

Выберите

select * from zeepdr;

ведет себя так, как вы ожидаете. Более того, если вы хотите получить только общие данные от всех пользователей, вы можете использовать ключевое слово ONLY:

select * from ONLY user_;

или в SQLAlchemy

result = table.select().with_hint(table, 'ONLY', 'postgresql')

Дополнительная информация: ограничение

Наследуются только проверочные или ненулевые константы, если вы не используете NO INHERIT. Другие типы не наследуются.

Не в последнюю очередь

Еще немного информации о наследовании и SQLAlchemy здесь

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