Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从代码而不是数据库的角度主动避免重复行?_Python_Mysql_Python 2.7_Sqlalchemy - Fatal编程技术网

Python 如何从代码而不是数据库的角度主动避免重复行?

Python 如何从代码而不是数据库的角度主动避免重复行?,python,mysql,python-2.7,sqlalchemy,Python,Mysql,Python 2.7,Sqlalchemy,我得到了一个名为tb\u user\u grait的表,它保存了客户的头像,它的模式看起来很简单 CREATE TABLE `tb_user_portrait` ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 'primary key', user_id BIGINT NOT NULL DEFAULT 0 COMMENT 'custormer id', portrait_hash CHAR(255) NOT NULL DEFAULT

我得到了一个名为
tb\u user\u grait
的表,它保存了客户的头像,它的模式看起来很简单

CREATE TABLE `tb_user_portrait` (
    id BIGINT NOT NULL AUTO_INCREMENT COMMENT 'primary key',
    user_id BIGINT NOT NULL DEFAULT 0 COMMENT 'custormer id',
    portrait_hash CHAR(255) NOT NULL DEFAULT '' COMMENT 'portrait image hash',
    is_valid TINYINT NOT NULL DEFAULT 1 COMMENT 'validation flag of this row',
    primary key(id)
)
我没有设置任何唯一的密钥,因为客户可能会多次上传头像。但是,每个用户应该只有一个有效的肖像(即每个用户只能有一个
is\u valid=1
记录)

我处理上传操作的代码也很简单

def upload(user_id, portrait_hash, is_valid=1):
    # find the last is_valid=1 records, and set invalid
    portrait = DBSession().query(UserPortrait).\
        filter(UserPortrait.user_id == user_id).\
        filter(UserPortrait.is_valid == 1).\
        scalar()
    if portrait:
        portrait.is_valid = 0
        DBSession().add(portrait)
    # create new valid portrait and save it to db
    new_portrait = UserPortrait(
        user_id=user_id,
        portrait_hash=portrait_hash,
        is_valid=is_valid)
    DBSession().add(new_portrait)
    DBSession().commit()
虽然我首先找到了有效记录并将其设置为无效,但我总是遇到
MultipleRowsFound
,并且数据库中有多个记录(
is\u valid=1

顺便说一下,我使用了SQLAlchemy并打开了
session.autoflush

我想知道为什么会这样?有什么最佳实践可以避免这种情况吗?

来自SQLAlchemy:

autoflush–如果为True,则所有查询操作将在继续之前对此会话发出flush()调用。这是一个方便的特性,因此不需要重复调用flush(),数据库查询就可以检索结果。自动刷新通常与autocommit=False一起使用。在这种情况下,很少需要显式调用flush();通常只需调用commit()(刷新)即可完成更改

所以,基本上您不会将更改提交到数据库,这就是为什么它不起作用,并且您有多条记录
is\u invalid=1

尝试手动操作,而不是打开会话。自动刷新,因此:

...
if portrait:
    portrait.is_valid = 0
    DBSession().add(portrait)
    DBSession().flush() # <-- here

new_portrait = UserPortrait(
    user_id=user_id,
    portrait_hash=portrait_hash,
    is_valid=is_valid)
...
只需使用:

    DBSession().commit()
来自SQLAlchemy:

autoflush–如果为True,则所有查询操作将在继续之前对此会话发出flush()调用。这是一个方便的特性,因此不需要重复调用flush(),数据库查询就可以检索结果。自动刷新通常与autocommit=False一起使用。在这种情况下,很少需要显式调用flush();通常只需调用commit()(刷新)即可完成更改

所以,基本上您不会将更改提交到数据库,这就是为什么它不起作用,并且您有多条记录
is\u invalid=1

尝试手动操作,而不是打开会话。自动刷新,因此:

...
if portrait:
    portrait.is_valid = 0
    DBSession().add(portrait)
    DBSession().flush() # <-- here

new_portrait = UserPortrait(
    user_id=user_id,
    portrait_hash=portrait_hash,
    is_valid=is_valid)
...
只需使用:

    DBSession().commit()