Sqlalchemy - 一对多用户到位

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sqlalchemy - 一对多用户到位相关的知识,希望对你有一定的参考价值。

希望一切安好。我很难找到如何用flask和SQLALCHEMY编写这个db功能。

我希望能够向已经存在于数据库中的站点注册用户。

注册它们时,我希望路由能够将该用户分配给db中的站点模型。我想这样做的原因是我以后可以向连接到特定站点的所有用户发送消息,或者向所有站点的所有用户发送消息。

这是我目前的用户和网站模型:

class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
site = db.Column(db.String())
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
adminstatus = db.Column(db.Boolean)
user_data = db.relationship('Rma', backref='userdata', lazy=True)
# sites = db.relationship('Sites', secondary=usertosite, backref=db.backref('sites', lazy='dynamic'))

def __repr__(self):
    return f"User('{self.username}, '{self.email}')"

class Sites(db.Model):
id = db.Column(db.Integer, primary_key=True)
sitename = db.Column(db.String(), nullable=False)
contractstart = db.Column(db.String(), nullable=False)
contractend = db.Column(db.String(), nullable = False)
hwkey = db.Column(db.String(), nullable=False)
stations = db.Column(db.String(), nullable=False)
printers = db.Column(db.String(), nullable = False)
remprinters = db.Column(db.String(), nullable = False)
bof = db.Column(db.Boolean())
processor = db.Column(db.String(), nullable = False)
giftopt = db.Column(db.String(), nullable = False)

这是我的注册表

# REGISTER NEW USER
@app.route('/register', methods=['POST', 'GET'])
@login_required
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
        user = User(site = form.site.data, username = form.username.data, email = form.email.data, password = hashed_pw, adminstatus= form.admin_status.data)
        db.create_all()
        db.session.add(user)
        db.session.commit()
        flash(f"{form.username.data} has been added!")
        return redirect(url_for('dash'))

    return render_template('register.html', name = 'login', form=form)

我不知道如何通过将表单添加到数据库中来将特定模型中的所有表单元素添加到数据库中。如果我尝试一对多关系,我将不得不将Sites模型及其所有元素与特定用户一起分配,这不是理想的,因为该站点已经在db中创建。我是一个超级菜鸟,我可能错过了一些步骤,但请尽可能提供帮助。多谢你们。

答案

您需要使用外键。

class User(db.Model, UserMixin):
    ...
    site = db.Column(db.Integer, db.ForeignKey('sites.id'))

然后,当您将User信息输入数据库时​​,您将提供作为Sites存在的站点的主键ID。您可以在路由中执行此操作,也可以提供基于关键字执行此操作的初始化覆盖功能,例如:

class User(..):
    ...
    def __init__(self, **kwargs):
        if 'site' in kwargs:
             site_id = db.session.query(Sites).filter(Sites.sitename == kwargs['site']).one().id
             kwargs['site'] = site_id
        super().__init__(**kwargs)

请注意,默认情况下我认为mysql或SQLite不会强制执行外键一致性,我个人觉得这很烦人,你可能会在yoru数据库中获得NULL条目,但是你可能没想到它们,但是POSTGRES确实强制执行它。但是,在sqlalchemy中可以执行一些操作来强制执行mySQL和SQLlite中的外键一致性。

以上是关于Sqlalchemy - 一对多用户到位的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy 一对多关系澄清

嵌套的一对多关系 sqlalchemy 过滤

如何级联删除一对多数据 sqlalchemy

flask-sqlalchemy 一对一,一对多,多对多操作

SQLAlchemy_定义(一对一/一对多/多对多)关系

SQLAlchemy外键的使用