mariadb-соединитель executemany выдает DataError - PullRequest
1 голос
/ 03 мая 2020

Я пытаюсь реализовать несколько простых SQL операторов вставки с python -mariadb-connector , но не могу понять, что я делаю неправильно.

База данных выглядит так:

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

Я не уверен, как выполняется executemany, но я думаю, что он должен выполнить что-то вроде следующего SQL -запроса:

INSERT INTO `forums` (`id`) VALUES (1), (2), (3);

INSERT INTO `accounts` (`id`) VALUES (1), (2), (3), (4);

INSERT INTO `posts` (`id`, `forum_id`, `account_id`) VALUES (6, 3, 1);

INSERT INTO `comments` (`id`, `post_id`, `account_id`, `parent_id`)
VALUES (1, 6, 1, NULL), (2, 6, 2, 1);

, который прекрасно работает для меня ...

Это так? ошибка или я здесь что-то не так делаю?

1 Ответ

0 голосов
/ 03 мая 2020

Я потратил некоторое время

    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, Нет) должен быть уже зафиксирован в базе данных, и при массовой вставке фиксация выполняется после того, как все вставки находятся в базе данных, но первый кортеж отсутствует в то время, когда его нет

поэтому, если вы сделаете это, обе строки появятся в базе данных (я также зафиксировал все остальные таблицы после массовой вставки):

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...