为了账号安全,请及时绑定邮箱和手机立即绑定

如何建立允许不同类型用户在 SqlAlchemy 中注册的数据库关系

如何建立允许不同类型用户在 SqlAlchemy 中注册的数据库关系

万千封印 2022-07-05 17:06:40
我有不同的用户,他们将访问平台中的不同功能,并拥有与他们相关的不同信息。我根据下图实现了这些表,其中我有一个包含身份验证数据的用户表,我有两个表,用于两种用户类型及其相应的信息。我与“zpeedr <-> user”有一对一的关系,对于“merchant <-> user”也是如此。我将 flask_sqlalchemy 与 postgresql 数据库一起使用。如果不按预期将其与现有 user.id 关联,则无法实例化 zpeedr 或商家类型用户。我的问题是,使用此设置,我可以为 zpeedr 和商家分配相同的 user_id。我如何确保一个 user.id 只能由 zpeedr 用户或商家用户关联?我创建表的简化代码是:类用户(UserMixin,db.Model):    '''用户属性'''    id = db.Column(db.Integer, primary_key=True)    角色 = db.Column(db.String(10), nullable=False)    名称 = db.Column(db.String(50), nullable=False)    电子邮件 = db.Column(db.String(50),唯一 = True,可为空 = False)    password_hash = db.Column(db.String(250), nullable=False)    状态 = 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)    商家 = db.relationship('Merchant', backref='user', uselist=False)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 = merchantZpeedr 类(db.Model):    ''' Zpeedr 属性 '''    id = db.Column(db.Integer, primary_key=True)    # 用户表的外键    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False, unique=True)    地址 = db.Column(db.String(200), nullable=False)    位置 = db.Column(db.String(50), nullable=False)    邮政编码 = db.Column(db.String(10), nullable=False)    联系人 = db.Column(db.String(15), nullable=False)    增值税 = db.Column(db.String(20), nullable=False, unique=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
查看完整描述

1 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

如果表用户的目的只是存储公共数据,您可以使用 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_")

基本用法


插入


根据我对山羊的看法,您不需要既不是商人也不是 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 的更多信息here


查看完整回答
反对 回复 2022-07-05
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信