Python mariadb连接器executemany抛出数据错误

Python mariadb连接器executemany抛出数据错误,python,mysql,database,mariadb,sql-insert,Python,Mysql,Database,Mariadb,Sql Insert,我试图用实现几个简单的SQL insert语句,但无法找出我做错了什么 数据库如下所示: SET FOREIGN_KEY_CHECKS = false; CREATE OR REPLACE TABLE `forums` ( `id` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE OR REPLACE TABLE `accounts` ( `id`

我试图用实现几个简单的SQL insert语句,但无法找出我做错了什么

数据库如下所示:

SET FOREIGN_KEY_CHECKS = false;

CREATE OR REPLACE TABLE `forums` (
  `id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE OR REPLACE TABLE `accounts` (
  `id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE OR REPLACE TABLE `posts` (
  `id` int(10) unsigned NOT NULL,
  `forum_id` int(10) unsigned NOT NULL,
  `account_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `posts_forum_fk` (`forum_id`),
  KEY `posts_account_fk` (`account_id`),
  CONSTRAINT `posts_account_fk` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`),
  CONSTRAINT `posts_forum_fk` FOREIGN KEY (`forum_id`) REFERENCES `forums` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE OR REPLACE TABLE `comments` (
  `id` int(10) unsigned NOT NULL,
  `post_id` int(10) unsigned NOT NULL,
  `account_id` int(10) unsigned NOT NULL,
  `parent_id` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `comments_post_fk` (`post_id`),
  KEY `comments_account_fk` (`account_id`),
--  KEY `comments_comments_fk` (`parent_id`),
--  CONSTRAINT `comments_comments_fk` FOREIGN KEY (`parent_id`) REFERENCES `comments` (`id`),
  CONSTRAINT `comments_account_fk` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`),
  CONSTRAINT `comments_post_fk` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = true;
import mariadb


config = {
    "user": "db_user_name",
    "password": "db_passwd",
    "host": "db_host",
    "port": 3306,
    "database": "db_name"
}


if __name__ == '__main__':
    with mariadb.connect(**config) as conn:
        cur = conn.cursor()
        cur.executemany(
            "INSERT INTO `forums` (`id`) VALUES (?)",
            [(1,), (2,), (3,)]
        )
        cur.executemany(
            "INSERT INTO `accounts` (`id`) VALUES (?)",
            [(1,), (2,), (3,), (4,)]
        )
        cur.executemany(
            "INSERT INTO `posts` (`id`, `forum_id`, `account_id`) VALUES (?, ?, ?)",
            [(6, 3, 1)]
        )
        cur.executemany(
            "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
            [(1, 6, 1, None), (2, 6, 2, 1)]
        ) # exception happens here
插入数据的代码如下所示:

SET FOREIGN_KEY_CHECKS = false;

CREATE OR REPLACE TABLE `forums` (
  `id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE OR REPLACE TABLE `accounts` (
  `id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE OR REPLACE TABLE `posts` (
  `id` int(10) unsigned NOT NULL,
  `forum_id` int(10) unsigned NOT NULL,
  `account_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `posts_forum_fk` (`forum_id`),
  KEY `posts_account_fk` (`account_id`),
  CONSTRAINT `posts_account_fk` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`),
  CONSTRAINT `posts_forum_fk` FOREIGN KEY (`forum_id`) REFERENCES `forums` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE OR REPLACE TABLE `comments` (
  `id` int(10) unsigned NOT NULL,
  `post_id` int(10) unsigned NOT NULL,
  `account_id` int(10) unsigned NOT NULL,
  `parent_id` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `comments_post_fk` (`post_id`),
  KEY `comments_account_fk` (`account_id`),
--  KEY `comments_comments_fk` (`parent_id`),
--  CONSTRAINT `comments_comments_fk` FOREIGN KEY (`parent_id`) REFERENCES `comments` (`id`),
  CONSTRAINT `comments_account_fk` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`),
  CONSTRAINT `comments_post_fk` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = true;
import mariadb


config = {
    "user": "db_user_name",
    "password": "db_passwd",
    "host": "db_host",
    "port": 3306,
    "database": "db_name"
}


if __name__ == '__main__':
    with mariadb.connect(**config) as conn:
        cur = conn.cursor()
        cur.executemany(
            "INSERT INTO `forums` (`id`) VALUES (?)",
            [(1,), (2,), (3,)]
        )
        cur.executemany(
            "INSERT INTO `accounts` (`id`) VALUES (?)",
            [(1,), (2,), (3,), (4,)]
        )
        cur.executemany(
            "INSERT INTO `posts` (`id`, `forum_id`, `account_id`) VALUES (?, ?, ?)",
            [(6, 3, 1)]
        )
        cur.executemany(
            "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
            [(1, 6, 1, None), (2, 6, 2, 1)]
        ) # exception happens here
执行此操作时,我得到以下错误:

Traceback (most recent call last):
  File ".../db_test.py", line 28, in <module>
    cur.executemany(
mariadb.DatabaseError.DataError: Invalid parameter type at row 2, column 4
这对我来说很好

这是一个bug还是我做错了什么?

我花了一段时间

    cur.executemany(
        "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
        [(1, 6, 1, None), (2, 6, 2, 1)]
    ) 
但是在注释表中,您有这个约束

CONSTRAINT `comments_comments_fk` FOREIGN KEY (`parent_id`) REFERENCES `comments` (`id`),
在输入(2,6,2,1)元组(1,6,1,None)之前,必须在数据库中提交元组(1,6,1,None),并且在批量插入中,提交是在所有插入都在数据库中之后进行的,但第一个元组当时不在数据库中

因此,如果这样做,这两行都将出现在数据库中(我还提交了大容量插入后的所有其他表):

MAriaDB

 mycursor.execute(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
    (1, 6, 1,None ))
 mydb.commit()    
 mycursor.executemany(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
    [ (2, 6, 2, 1)])    
 mydb.commit()
MySQL

 sql = """INSERT INTO forums (id) VALUES (%s)"""
 val = [("1",), ("2",), ("3",)]
 mycursor.executemany(sql,val)
 mydb.commit()
 mycursor.executemany( 
    "INSERT INTO accounts (id) VALUES (%s)",
    [(1,), (2,), (3,), (4,)]
 )
 mydb.commit()
 mycursor.executemany(
    "INSERT INTO posts (id, forum_id, account_id) VALUES (%s, %s, %s)",
    [(6, 3, 1)]
 )
 mydb.commit()
 mycursor.execute(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (%s, %s, %s, %s)",
    (1, 6, 1,None ))
 mydb.commit()    
 mycursor.executemany(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (%s, %s, %s, %s)",
    [ (2, 6, 2, 1)])    
 mydb.commit()
我花了我一段时间

    cur.executemany(
        "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
        [(1, 6, 1, None), (2, 6, 2, 1)]
    ) 
但是在注释表中,您有这个约束

CONSTRAINT `comments_comments_fk` FOREIGN KEY (`parent_id`) REFERENCES `comments` (`id`),
在输入(2,6,2,1)元组(1,6,1,None)之前,必须在数据库中提交元组(1,6,1,None),并且在批量插入中,提交是在所有插入都在数据库中之后进行的,但第一个元组当时不在数据库中

因此,如果这样做,这两行都将出现在数据库中(我还提交了大容量插入后的所有其他表):

MAriaDB

 mycursor.execute(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
    (1, 6, 1,None ))
 mydb.commit()    
 mycursor.executemany(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (?, ?, ?, ?)",
    [ (2, 6, 2, 1)])    
 mydb.commit()
MySQL

 sql = """INSERT INTO forums (id) VALUES (%s)"""
 val = [("1",), ("2",), ("3",)]
 mycursor.executemany(sql,val)
 mydb.commit()
 mycursor.executemany( 
    "INSERT INTO accounts (id) VALUES (%s)",
    [(1,), (2,), (3,), (4,)]
 )
 mydb.commit()
 mycursor.executemany(
    "INSERT INTO posts (id, forum_id, account_id) VALUES (%s, %s, %s)",
    [(6, 3, 1)]
 )
 mydb.commit()
 mycursor.execute(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (%s, %s, %s, %s)",
    (1, 6, 1,None ))
 mydb.commit()    
 mycursor.executemany(
    "INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`) VALUES (%s, %s, %s, %s)",
    [ (2, 6, 2, 1)])    
 mydb.commit()

这是我的第一个猜测,这就是为什么我注释掉了这些行。错误仍然出现,我100%确信这个约束实际上并不存在:正如我在回答中所写的,您还必须提交用作引用的其他插入。在VS代码中,执行一个接一个的调试非常简单,它会向您显示退出的位置。我添加了io在mysql上使用的全部代码。论坛现在不同了,因为我不明白python在这种情况下是如何工作的,我想你误解了。。。您所指的约束从未存在过。在本例中,我没有将其注释掉,而只是将其从代码中删除,这是我的错。为了更清楚地说明这一点,我做了一个简单的反例,偶然发现了这个bug(我想它就是其中之一)。executemany()似乎无法在一列中处理混合类型。如果我更改代码,使所有的parent_id条目要么为None,要么为某个整数,它就可以正常工作。这也是代码工作的原因。您在两个单独的语句中分隔了该列中的不同类型。是的,这是正确的,连接器抛出了一个无法解决的错误,而不是我的代码。在我的数据库中,所有约束都处于活动状态。我认为这是一个bug,所以你应该回到开发者那里报告它。我正在监视我的服务器,但它从未收到任何插入。然后我添加了comits,让它一直运行到评论。唯一的解决办法就是我给你看的。我创建了一张罚单。这是我的第一个猜测,这就是为什么我注释掉了这些行。错误仍然出现,我100%确信这个约束实际上并不存在:正如我在回答中所写的,您还必须提交用作引用的其他插入。在VS代码中,执行一个接一个的调试非常简单,它会向您显示退出的位置。我添加了io在mysql上使用的全部代码。论坛现在不同了,因为我不明白python在这种情况下是如何工作的,我想你误解了。。。您所指的约束从未存在过。在本例中,我没有将其注释掉,而只是将其从代码中删除,这是我的错。为了更清楚地说明这一点,我做了一个简单的反例,偶然发现了这个bug(我想它就是其中之一)。executemany()似乎无法在一列中处理混合类型。如果我更改代码,使所有的parent_id条目要么为None,要么为某个整数,它就可以正常工作。这也是代码工作的原因。您在两个单独的语句中分隔了该列中的不同类型。是的,这是正确的,连接器抛出了一个无法解决的错误,而不是我的代码。在我的数据库中,所有约束都处于活动状态。我认为这是一个bug,所以你应该回到开发者那里报告它。我正在监视我的服务器,但它从未收到任何插入。然后我添加了comits,让它一直运行到评论为止。唯一的解决办法就是我给你看的。我创建了一张罚单。