sqlalchemy在提交前避免在session()中重复

zc0qhyus  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(430)

在尝试使用session.merge()使用sqlalchemy提交行时,出现了一个重复的错误。
我认为这是因为我获取数据的数据库允许重复的列“散列”,而新的不允许。
在提交之前,有没有一种简单的方法来避免或删除当前会话中的重复项?
举个例子:

from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.automap import automap_base
    from src.python.utils import _gen_relationship

    engine = create_engine('mysql+pymysql://{user}:{pssw}@{host}/{db}?charset=utf8'.
                               format(user=config['user'],
                                      pssw=config['password'],
                                      host=config['host'],
                                      db=config['database'])
                               )

    database = [
        {'c_hash': 'd182jd012jd102jd1', 'date': '2017-01-01', 'text': 'oijwdqoijwdqoiqwdm'},
        {'c_hash': 'apiowjdaowndoaiwjda', 'date': '2017-01-01', 'text': 'oijwdqoijwdqoiqwdm'},
        {'c_hash': 'd182jd012jd102jd1', 'date': '2017-01-02', 'text': 'adawdawdawd'}
    ]

    Base = automap_base()
    Base.prepare(engine, reflect=True, generate_relationship=_gen_relationship)

    # load necessary table information
    Mytable = Base.classes.mytable

    Session = sessionmaker(bind=engine, autoflush=False)
    session = Session()

    for row in database:
        new_row = {
            'hash': row['c_hash'],
            'date': row['date'],
            'text': row['text']
        }

        session.merge(Mytable(**new_row))
    session.commit()

谢谢您

hts6caw3

hts6caw31#

在应用程序中进行“重复数据消除”似乎更好:

seen = set()

# Reversed so that the last row wins.

for row in reversed(database):
    c_hash = row['c_hash']
    if c_hash not in seen:
        session.merge(Mytable(hash=c_hash,
                              date=row['date'],
                              text=row['text']))
        seen.add(c_hash)

理论上,您也可以让sqlalchemy处理重复数据消除:

for row in database:
    session.merge(Mytable(hash=row['c_hash'],
                          date=row['date'],
                          text=row['text']))
    session.flush()

诀窍是在两者之间进行刷新,以便以后的合并将查询db并找到现有行,但是与其他解决方案相比,这将执行更多的查询。

相关问题