简体   繁体   English

SQLAlchemy 执行查询,但未更新,尽管原始查询在 SQL IDE 中工作正常

[英]SQLAlchemy execute query but does not update despite raw query working fine in a SQL IDE

I have a query that works fine in a SQL editor:我有一个在 SQL 编辑器中运行良好的查询:

UPDATE users mu 
JOIN (SELECT 
        min.user_id as user_id, 
        (max.total_followers - min.total_followers) as progression
    FROM(select user_id, measurement_date, total_followers
    from followers_totals ft 
        where measurement_date = (select max(measurement_date) from followers_totals as f where f.user_id = ft.user_id
        and date_format(ft.measurement_date, '%%Y-%%m-%%d') >= date_format(date_sub(CURDATE(), interval 7 day), '%%Y-%%m-%%d'))) max
    JOIN (select user_id, measurement_date, total_followers
        from followers_totals ft 
        where measurement_date = (select min(measurement_date) from followers_totals as f where f.user_id = ft.user_id
        and date_format(ft.measurement_date, '%%Y-%%m-%%d') >= date_format(date_sub(CURDATE(), interval 7 day), '%%Y-%%m-%%d'))) min
    ON max.user_id = min.user_id
    WHERE min.user_id = '123456' and max.user_id = '123456') progression 
ON progression.user_id = mu.user_id
SET mu.followers_count_progress_7D = progression.progression
WHERE progression.user_id is not null;

I try to execute the same query from SQLAlchemy using the execute function:我尝试使用执行 function 从 SQLAlchemy 执行相同的查询:

import sqlalchemy
from sqlalchemy import create_engine, Table, MetaData, exc

eng = create_engine('mysql://xxxxxxxxxxxxxxxxxxxxxxxxxxxx')
con = eng.connect()    

try:
    query = """UPDATE users mu 
                JOIN (SELECT 
                        min.user_id as user_id, 
                        (max.total_followers - min.total_followers) as progression
                    FROM(select user_id, measurement_date, total_followers
                    from followers_totals ft 
                        where measurement_date = (select max(measurement_date) from followers_totals as f where f.user_id = ft.user_id
                        and date_format(ft.measurement_date, '%%Y-%%m-%%d') >= date_format(date_sub(CURDATE(), interval 7 day), '%%Y-%%m-%%d'))) max
                    JOIN (select user_id, measurement_date, total_followers
                        from followers_totals ft 
                        where measurement_date = (select min(measurement_date) from followers_totals as f where f.user_id = ft.user_id
                        and date_format(ft.measurement_date, '%%Y-%%m-%%d') >= date_format(date_sub(CURDATE(), interval 7 day), '%%Y-%%m-%%d'))) min
                    ON max.user_id = min.user_id
                    WHERE min.user_id = '123456' and max.user_id = '123456') progression 
                ON progression.user_id = mu.user_id
                SET mu.followers_count_progress_7D = progression.progression
                WHERE progression.user_id is not null;"""
    rs = con.execute(query)
    print(rs)
except exc.SQLAlchemyError as e:
    print (e)

No exception is returned and print(rs) result in a return proxy as expected.不返回异常,并且 print(rs) 按预期返回代理。 However the db does not get updated with SQLAlchemy while it is updated with a SQL editor.但是,数据库不会使用 SQLAlchemy 进行更新,而是使用 SQL 编辑器进行更新。 Is there some part of my query that is not supported by SQL Alchemy? SQL Alchemy 不支持我的查询的某些部分吗?

I initially thought it would be the escape of the % in the date format, but different tests show that simpler queries run as expected using this escape writing.我最初认为这将是日期格式中 % 的转义,但不同的测试表明,使用这种转义写作可以按预期运行更简单的查询。

EDIT: after using echo=True in the engine creation as suggested above I can see that the query formatting is preserve, the commit is done.编辑:按照上面的建议在引擎创建中使用 echo=True 后,我可以看到查询格式被保留,提交完成。 I copied pasted the ouput of the echo to a sql editor and the query works well, but with sqlalchemy it does not update at all.我将回声的输出复制粘贴到 sql 编辑器,查询运行良好,但使用 sqlalchemy 它根本不会更新。

EDIT2: tried adding autocommit=True with same result.... Logs are showing: EDIT2:尝试添加具有相同结果的 autocommit=True .... 日志显示:

2021-02-14 11:21:21,387 INFO sqlalchemy.engine.base.Engine ()
2021-02-14 11:21:21,389 INFO sqlalchemy.engine.base.Engine UPDATE users mu 
                JOIN (
                    SELECT min.user_id as user_id, 
                        (max.total_followers - min.total_followers) as progression 
                    FROM(
                        select user_id, measurement_date, total_followers 
                 ....
                ON progression.user_id = mu.user_id 
                SET mu.followers_count_progress_7D = progression.progression 
                WHERE progression.user_id is not null;
2021-02-14 11:21:21,389 INFO sqlalchemy.engine.base.Engine ()
2021-02-14 11:21:21,393 INFO sqlalchemy.engine.base.Engine COMMIT
0

The user used to connect has all permissions:用于连接的用户拥有所有权限:

GRANT ALL ON *.* TO 'user1'@'%';

Simpler update queries run on SQLAlchemy are actually working.在 SQLAlchemy 上运行的更简单的更新查询实际上正在运行。

EDIT 3: Interestingly it seems that this only happens for certain ids, but not all.编辑 3:有趣的是,这似乎只发生在某些 id 上,但不是全部。 How can something ID dependant work remotely but not locally...?依赖 ID 的东西如何远程工作而不是本地工作......?

Since the debug printing didn't seem to give enough info to solve the issue, I'm going to assume that it is indeed an issue with actually committing changes to the DB, so, like other people have mentioned in various other questions (such as: setting autocommit to 1 in mysql ), you should try explicitly using autocommit=True .由于调试打印似乎没有提供足够的信息来解决问题,我将假设它确实是实际提交对数据库的更改的问题,因此,就像其他人在其他各种问题中提到的那样(例如如: 在 mysql 中将 autocommit 设置为 1 ),您应该明确尝试使用autocommit=True

You can test this either with a with statement such as:您可以使用with语句对此进行测试,例如:

with engine.connect().execution_options(autocommit=True) as conn:
    conn.execute(query)

or just appending .execution_options(autocommit=True) to your existing code:或者只是将.execution_options(autocommit=True)附加到您现有的代码中:

conn.execute(query).execution_options(autocommit=True)

Note though that execution_option 's autocommit parameter will be deprecated with SQLAlchemy 1.4 and that the replacement will be to set transaction isolation levels as shown here .请注意,尽管在 SQLAlchemy 1.4 中不推荐使用execution_optionautocommit参数,并且替换将是设置事务隔离级别,如此处所示

Just to reiterate, it seems like MySQL sets the autocommit value to 0 internally, meaning that it uses a transaction which needs to be .commit() ed to propagate it to the DB.重申一下,似乎 MySQL 在内部将自动提交值设置为 0,这意味着它使用需要.commit()编辑的事务将其传播到数据库。 Hope that actually solves the issue as I'm not set up to test this on my machine at the moment.希望这实际上解决了这个问题,因为我目前还没有准备好在我的机器上进行测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM