循环遍历数组以使用 Flask-SqlAlchemy 插入的最佳方法 [关闭]

问题描述 投票:0回答:0

晚上好,

我有一个 Flask 应用程序和以下数组,该数组是使用随机散布的不同 SQLAlchemy 对象构建的。我正在尝试遍历数组并将对象插入数据库。我第一次运行阵列时没有遇到任何问题,但我希望可以选择多次运行它并使用它来为数据库播种。如果我在稍后要将它们插入数据库的位置进行更改,我想再次运行命令,让它遍历数组,忽略数据库中已经存在的项目并添加那些不是。

命令行:

(pde) PS C:\Users\123123\Developer\app> flask cmd seed
2023-03-10 18:10:14,287 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2023-03-10 18:10:14,298 INFO sqlalchemy.engine.Engine INSERT INTO office (name, abbreviation, sort_order) VALUES (?, ?, ?)
2023-03-10 18:10:14,298 INFO sqlalchemy.engine.Engine [generated in 0.00069s] ('57', '57', None)
2023-03-10 18:10:14,304 INFO sqlalchemy.engine.Engine ROLLBACK
(sqlite3.IntegrityError) UNIQUE constraint failed: office.name
[SQL: INSERT INTO office (name, abbreviation, sort_order) VALUES (?, ?, ?)]
[parameters: ('57', '57', None)]
(Background on this error at: https://sqlalche.me/e/14/gkpj)
This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlite3.IntegrityError) UNIQUE constraint failed: office.name
[SQL: INSERT INTO office (name, abbreviation, sort_order) VALUES (?, ?, ?)]
[parameters: ('57', '57', None)]
(Background on this error at: https://sqlalche.me/e/14/gkpj) (Background on this error at: https://sqlalche.me/e/14/7s2a)

cli.py

@cmd_blueprint.cli.command('seed')
@with_appcontext
def seed():
    seed = [
    Office(name="57", abbreviation="57"),
    Office(name="57I", abbreviation="57I"),
    ]

    for object in seed:
        try:
            db.session.add(object)
            db.session.commit()
        except Exception as e:
            print(f"{e}")
            db.session.rollback

models.py

class BaseModel(db.Model):
    __abstract__ = True
    
    def __repr__(self) -> str:
        # return self._repr(id=self.id) # Returns just the id
        params = ', '.join(f'{k}={v}' for k, v in todict(self).items())
        return f"<{self.__class__.__name__}({params})>"

    def _repr(self, **fields: typing.Dict[str, typing.Any]) -> str:
        '''
        Helper for __repr__
        '''
        field_strings = []
        at_least_one_attached_attribute = False
        for key, field in fields.items():
            try:
                field_strings.append(f'{key}={field!r}')
            except sa.orm.exc.DetachedInstanceError:
                field_strings.append(f'{key}=DetachedInstanceError')
            else:
                at_least_one_attached_attribute = True
        if at_least_one_attached_attribute:
            return f"<{self.__class__.__name__}({','.join(field_strings)})>"
        return f"<{self.__class__.__name__} {id(self)}>"

# Helper Function for BaseModel

def todict(obj):
    """ Return the object's dict excluding private attributes, 
    sqlalchemy state and relationship attributes.
    """
    excl = ('_sa_adapter', '_sa_instance_state')
    return {k: v for k, v in vars(obj).items() if not k.startswith('_') and
            not any(hasattr(v, a) for a in excl)}

class Office(BaseModel):
    __tablename__ = 'office'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), unique=True)
    abbreviation = db.Column(db.String(255))
    sort_order = db.Column(db.Integer)
    
    #Direct Model Relationships
    
    #Indirect Model Relationships
    organization_offices = db.relationship("OrganizationOffice", back_populates="office")

我继续收到这个错误:

(sqlite3.IntegrityError) UNIQUE constraint failed: office.name    
[SQL: INSERT INTO office (name, abbreviation, sort_order) VALUES (?, ?, ?)]
    [parameters: ('57', '57', None)]
    (Background on this error at: https://sqlalche.me/e/14/gkpj)
    This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlite3.IntegrityError) UNIQUE constraint failed: office.name
    [SQL: INSERT INTO office (name, abbreviation, sort_order) VALUES (?, ?, ?)]
    [parameters: ('57', '57', None)]
    (Background on this error at: https://sqlalche.me/e/14/gkpj) (Background on this error at: https://sqlalche.me/e/14/7s2a)

如果我在 try/except 循环中添加一个

finally: db.session.close
它可以工作,但是我在 cli.py 文件中进一步遇到问题,我尝试对一个对象运行选择查询并且我得到一个
sqlalchemy.exc.InvalidRequestError: Can't resolve value for column readiness_level_phase.id on object <ReadinessLevelPhase at 0x278f2845130>; the object is detached and the value was expired

我真正想做的就是遍历一个数组,如果它不存在就将它添加到数据库中。我已经根据 here 中 SQLAlchemy 文档中的示例构建了我的代码。给我指明正确的方向!

python arrays flask sqlalchemy flask-sqlalchemy
© www.soinside.com 2019 - 2024. All rights reserved.