【问题标题】:Pre-populate a Flask SQLAlchemy database预填充 Flask SQLAlchemy 数据库
【发布时间】:2021-02-23 16:39:45
【问题描述】:

我有两个模型,一个是包含两个 ID(first_id 和 second_id)的标识,第二个是用户。这个想法是只有授权用户才会被赋予他们的 first_id 和 second_id 对值。他们进入站点并通过输入两个 id 以及用户名和密码(他们在那里生成)来登录。

我想在这里实现两件事:

  1. 使用许多(比如 100 个)first_id/second_id 值预填充标识表,这些值将用作登录时的正确值对。

  2. 以这样一种方式设置 User 类,即只有当用户在登录表单中输入正确的 first_id/second_id 对时,他们才能登录(推测这涉及以某种方式使用标识表检查表单数据)。

这里是模型类:

class Identification(db.Model):

id = db.Column(db.Integer, primary_key=True)
first_id= db.Column(db.Text, unique=True)
second_id= db.Column(db.Text, unique=True)

def __init__(self, first_id, second_id):
    self.first_id= first_id
    self.second_id= second_id

def __repr__(self):
    return f"ID: {self.id}, first_id: {self.first_id}, second_id: {self.second_id}"



class User(db.Model, UserMixin):

__tablename__ = 'user'

first_id= db.relationship('Identification', backref = 'identificationFID', uselist=False)
second_id = db.relationship('Identification', backref = 'identificationSID', uselist=False)
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.Text, unique=True, index=True)
password_hash = db.Column(db.Text(128))
identification_id = db.Column(db.Integer, db.ForeignKey('identification.id'), unique=True)
first_id = db.Column(db.Text, unique=True)
second_id = db.Column(db.Text, unique=True)

我很感激任何帮助,因为我正在努力,这真的超出了我对 python/Flask 的理解。谢谢大家!

【问题讨论】:

    标签: python flask flask-sqlalchemy


    【解决方案1】:

    上面的答案对我不起作用,因为 create_tables() 函数作为 User 类的一部分,要求我传递该类的实例。 我想出的解决方案是在db.create_all() 之后调用该函数。由于 @app.before_first_request 装饰器,这似乎是一个拨打电话的好地方。

    初始化.py

    @app.before_first_request
    def create_tables():
        """Create Tables and populate certain ones"""
        db.create_all()
        from app.models.init_defaults import init_defaults
        init_defaults()
    

    init_defaults.py

    def init_defaults():
    """Pre-Populate Role Table"""
    if Role.query.first() is None:
        roles = ['Admin', 'Master', 'Apprentice']
        for role in roles:
            user_role = Role(access_level=role)
            if role != 'Apprentice':
                user_role.set_password('Passw0rd!')
            db.session.add(user_role)
        db.session.commit()
    pass
    

    由于装饰器,现在每个实例只调用一次函数。我可以想象的另一个解决方案是使用事件: https://dzone.com/articles/how-to-initialize-database-with-default-values-in

    注意:这是一个不适合生产的开发解决方案。

    【讨论】:

      【解决方案2】:

      您可以使用模拟数据来填充这些表格。 在这个 py 文件中创建一个函数,您可以在其中使用 ORM 将对象添加到 DB 然后调用 __init__.py 中的函数,该函数将在您的烧瓶服务器启动后填充数据。

      更新:-

      这里有一个代码供您参考。

      模型.py

      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import create_engine
      from sqlalchemy import Column, Integer, String
      from sqlalchemy.orm import sessionmaker
      
      Base = declarative_base()
      engine = create_engine('sqlite:///:memory:', echo=True)
      Session = sessionmaker(bind=engine)
      session = Session()
      
      class User(Base):
           \__tablename__ = 'users'
           id = Column(Integer, primary_key=True)
           name = Column(String)
           fullname = Column(String)
      
           #Create getter setters
      
          def create_tables():
              Base.metadata.create_all(engine)
              user = User()
              user.id=1
              user.name="ABC"
              user.fullname="ABCDEF"
              session.add(user)
              # similarly create more user objects with mock data and add it using session
      

      __init__.py

      from model import User
      User.create_tables()
      

      Reference

      【讨论】:

      • 您能否简要解释一下这个函数在实践中的样子?感谢您的回复
      • 我已经修改了评论。你可以检查:)
      • 我正在使用 SQLite。我认为语法会有所不同吗?
      • 不只是连接字符串(你声明引擎的地方)会根据你使用的数据库而改变..
      • 只是为了确认一下,def create_tables() 函数是在 User 类中发生的,还是缩进在 Stack Overflow 上的显示方式?
      猜你喜欢
      • 2012-08-22
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 1970-01-01
      • 2021-01-26
      • 2014-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多