为什么 SQLAlchemy 返回一个新的 rownum 但不将我的新行插入 MySQL?

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

我正在调试一段Python代码中出现的奇怪现象:


def insert_book(name):
   with engine.connect() as connection:
        insert_statement = sqlalchemy.text(
            """
            INSERT INTO books (title_id) 
            SELECT 
                title_id
            FROM titles
            WHERE name = :name;
            """
        ).bindparams(name=name)

        result = connection.execute(insert_statement)
       
        return result.lastrowid

我正在使用的 MySQL 数据库表的结构如下:

CREATE TABLE `titles` (
  `title_id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(36),
  PRIMARY KEY (`title_id`),
  UNIQUE KEY `name` (`name`)
);

CREATE TABLE `books` (
  `book_id` int NOT NULL AUTO_INCREMENT,
  `title_id` int DEFAULT NULL,
  PRIMARY KEY (`book_id`),
  KEY `client_id` (`title_id`),
  CONSTRAINT `titles_fk` FOREIGN KEY (`title_id`) REFERENCES `titles` (`title_id`)
);

两个表都已插入几行。

当我在 Flask 应用程序中运行 Python 代码(使用从

name
表获取的
titles
)并将 SQLAlchemy 指向我的 MySQL 数据库时,会发生两件事:

  1. result.lastrowid
    包含一个新的自动递增 int 值。
  2. 新行插入到表中。

当我重复此操作时,返回的 int 值会正确递增,但不会创建任何行。

我的问题是:为什么会发生这种情况以及如何解决它?

以下是主要使用的包:

  • Python 3.9.13
  • 烧瓶==2.2.2
  • PyMySQL==1.1.0
  • SQLAlchemy==2.0.19

请: 请不要指向其他公认更好的 SQLAlchemy API。我想了解为什么这段特定的代码行为不当。谢谢你。

更新:我检查了 MySQL 云实例的日志,发现了与插入失败相对应的错误:

中止连接...到数据库:'...'用户:'...'主机:'...'(读取通信数据包时出错)。”

python mysql sqlalchemy pymysql
1个回答
0
投票
with engine.connect() as conn:
    conn.exec_driver_sql("INSERT INTO my_table …")
print("Context manager exited.")

将自动回滚更改,因为未调用

conn.commit()
。在 SQLAlchemy 教程中,这被称为“随心所欲地提交”工作方式。

相比之下,

with engine.begin() as conn:
    conn.exec_driver_sql("INSERT INTO my_table …")
print("Context manager exited.")

当上下文管理器退出时将自动提交更改(除非发生错误)。这称为“开始一次”风格。

© www.soinside.com 2019 - 2024. All rights reserved.