Search code examples
mysqlpython-3.xmysql-connector-python

'Table doesn't exist' with creation using execute() function with 'multi=True' parameter


MySQL 5.6.

I don't understand why if I use multi=True parameter table is not created. I don't find any information about it in documentation. If I separate all queries it works, but I don't want to separate them.

from mysql import connector as connector

conn = connector.connect(
    user='root',
    password='root',
    host='127.0.0.1',
    database='ra'
)
conn.autocommit = True
cursor = conn.cursor(dictionary=True, buffered=True)

sql = """
DROP TABLE IF EXISTS tab01;
CREATE TABLE tab01 (nzu DECIMAL(5,0) PRIMARY KEY,
                    nbr DECIMAL(3,0) DEFAULT NULL,
                    nland DECIMAL(5,0) DEFAULT NULL,
                    nlandtype DECIMAL(5,0) DEFAULT NULL,
                    nzuarea DECIMAL(12,1) DEFAULT NULL,
                    nzuareaos DECIMAL(12,1) DEFAULT NULL) ENGINE = MyISAM;
INSERT INTO tab01 (SELECT zu.nzu, zu.nbr, zu.nland,
                    IF(ISNULL(lands.nlandtype),0,lands.nlandtype) AS nlandtype,
                    0.0 AS nzuarea, 0.0 AS nzuareaos
                    FROM (SELECT * FROM zu WHERE nhoz = '6204000001') AS zu
                    LEFT JOIN lands AS lands ON zu.nland=lands.nland
                    ORDER BY nzu);
"""
cursor.execute(sql, multi=True) 
cursor.execute('SELECT * FROM tab01') 
# mysql.connector.errors.ProgrammingError: 1146 (42S02): Table 'ra.tab01' doesn't exist
result = cursor.fetchone()

Solution

  • Are you sure your CREATE works? I believe ENGINE option has to be at the end of CREATE statement:

    CREATE TABLE tab01 (
     nzu DECIMAL(5,0) PRIMARY KEY,
     nbr DECIMAL(3,0) DEFAULT NULL,
     nland DECIMAL(5,0) DEFAULT NULL,
     nlandtype DECIMAL(5,0) DEFAULT NULL,
     nzuarea DECIMAL(12,1) DEFAULT NULL,
     nzuareaos DECIMAL(12,1) DEFAULT NULL
    ) ENGINE = MyISAM;
    

    Also this statement:

    cursor.execute(sql, multi=True)
    

    creates an iterator over the results. It looks like it's lazy (i.e., it executes SQL statements only as needed). You're never asking for the results for the second statement, so it is only executing the first one. Try:

    for _ in cursor.execute(sql, multi=True): pass