首页 > 解决方案 > 加快在 python 中提交 MySQL DB

问题描述

我有代码可以添加或更新 MySQL DB 中的行,具体取决于行 ID 是否已经存在。我有一个循环遍历所有 ID 以执行此操作,并单独提交每个 ID。

但是它非常慢。更新 200,000 行大约需要 20 分钟。我需要它更快。有谁知道我如何一次将多行提交到数据库?

到目前为止,以下是我的代码:

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@localhost/dbName'
db = SQLAlchemy(app)

class Example(db.Model):
        __tablename__ = 'sessionAttendances'
        _id = db.Column('_id', db.Unicode, primary_key=True)
        wondeID = db.Column('wondeID', db.Unicode)
        date = db.Column('date', db.Unicode)
        timezoneType = db.Column('timezoneType', db.Unicode)
        timezone = db.Column('timezone', db.Unicode)
        createdAt = db.Column('createdAt', db.Date)
        session = db.Column('session', db.Unicode)
        updatedAt = db.Column('updatedAt', db.Date)

        def __init__(self, _id, wondeID, date, timezoneType, timezone, createdAt, session, updatedAt):
            self._id = _id
            self.wondeID = wondeID
            self.date = date
            self.timezoneType = timezoneType
            self.timezone = timezone
            self.createdAt = createdAt
            self.session = session
            self.updatedAt = updatedAt

        @classmethod
        def add_or_update(cls, _id, wondeID, date, timezoneType, timezone, createdAt, session, updatedAt):
            entity = cls.query.filter_by(_id=row._id).first()

            if not entity:
                entity = cls(row._id, row.wondeID, row.date, row.timezoneType, row.timezone, row.createdAt, row.session, row.updatedAt)
                db.session.add(entity)
                db.session.commit()
                print("Adding Record")
            else:
                entity.wondeID = row.wondeID
                db.session.commit()
                print("Updating Record")

            return entity

for idx,row in sessionAttendance.iterrows():
    example = Example(row._id, row.wondeID, row.date, row.timezoneType, 
                      row.timezone, row.createdAt, row.session, row.updatedAt)
    example.add_or_update(row._id, row.wondeID, row.date, row.timezoneType, 
                          row.timezone, row.createdAt, row.session, row.updatedAt)

标签: pythonmysqlflask-sqlalchemy

解决方案


由于您的“id”是您的 pirmary 密钥,您可能需要使用 session.merge() 。

https://docs.sqlalchemy.org/en/13/orm/session_state_management.html#merging

SQLAlchemy 中的此功能将自动创建或更新现有项目。

我还强烈建议您不要在每个项目之后都提交。这可能是您的代码中最大的延迟。如果您的循环两次不包含相同的“id”,我建议您在循环完成后提交。


推荐阅读