简体   繁体   English

_mysql_exceptions错误(1064,“检查与MySQL服务器版本对应的手册,以便在'default'附近使用正确的语法)VALUES

[英]_mysql_exceptions error(1064, "check the manual that corresponds to your MySQL server version for the right syntax to use near 'default) VALUES

I am trying to import CSVs to mysql database automatically using python script. 我正在尝试使用python脚本自动将CSV导入mysql数据库。 I used the script from https://bitbucket.org/richardpenman/csv2mysql to achieve this task. 我使用https://bitbucket.org/richardpenman/csv2mysql中的脚本来完成这项任务。 Below is the code: 以下是代码:

import os
import re
import sys
import csv
import time
import argparse
import collections
import MySQLdb
import warnings 
# suppress annoying mysql warnings
warnings.filterwarnings(action='ignore', category=MySQLdb.Warning) 

def get_type(s):
    """Find type for this string
    """
    # try integer type
    try:
        v = int(s)
    except ValueError:
        pass
    else:
        if abs(v) > 2147483647:
            return 'bigint'
        else:
            return 'int'
    # try float type
    try:
        float(s)
    except ValueError:
        pass
    else:
        return 'double'

    # check for timestamp
    dt_formats = (
        ('%Y-%m-%d %H:%M:%S', 'datetime'),
        ('%Y-%m-%d %H:%M:%S.%f', 'datetime'),
        ('%Y-%m-%d', 'date'),
        ('%H:%M:%S', 'time'),
    )
    for dt_format, dt_type in dt_formats:
        try:
            time.strptime(s, dt_format)
        except ValueError:
            pass
        else:
            return dt_type

    # doesn't match any other types so assume text
    if len(s) > 255:
        return 'text'
    else:
        return 'varchar(255)'


def most_common(l, default='varchar(255)'):
    """Return most common value from list
    """
    # some formats trump others
    if l:
        for dt_type in ('text', 'bigint'):
            if dt_type in l:
                return dt_type
        return max(l, key=l.count)
    return default


def get_col_types(input_file, max_rows=1000):
    """Find the type for each CSV column
    """
    csv_types = collections.defaultdict(list)
    print (os.getcwd())
    # os.chdir("scripts/CSV")
    reader = csv.reader(open(input_file))
    # test the first few rows for their data types
    for row_i, row in enumerate(reader):
        if row_i == 0:
            header = row
        else:
            for col_i, s in enumerate(row):
                data_type = get_type(s)
                csv_types[header[col_i]].append(data_type)

        if row_i == max_rows:
            break

    # take the most common data type for each row
    return [most_common(csv_types[col]) for col in header]


def get_insert(table, header):
    """Generate the SQL for inserting rows
    """
    field_names = ', '.join(header)
    field_markers = ', '.join('%s' for col in header)
    return 'INSERT INTO %s (%s) VALUES (%s);' % \
        (table, field_names, field_markers)


def format_header(row):
    """Format column names to remove illegal characters and duplicates
    """
    safe_col = lambda s: re.sub('\W+', '_', s.lower()).strip('_')
    header = []
    counts = collections.defaultdict(int)
    for col in row:
        col = safe_col(col)
        counts[col] += 1
        if counts[col] > 1:
            col = '{}{}'.format(col, counts[col])
        header.append(col)
    return header


def main(input_file, user, password, host, table, database, max_inserts=10000):
    print ("Importing `%s' into MySQL database `%s.%s'" % (input_file, database, table))
    db = MySQLdb.connect(host=host, user=user, passwd=password, charset='utf8')
    cursor = db.cursor()
    # create database and if doesn't exist
    cursor.execute('CREATE DATABASE IF NOT EXISTS %s;' % database)
    db.select_db(database)

    # define table
    print ("Analyzing column types ...")
    col_types = get_col_types(input_file)
    print (col_types)

    header = None
    for i, row in enumerate(csv.reader(open(input_file))):
        if header:
            while len(row) < len(header):
                row.append('') # this row is missing columns so pad blank values
            cursor.execute(insert_sql, row)
            if i % max_inserts == 0:
                db.commit()
                print ("commit")
        else:
            header = format_header(row)
            print ("Inserting rows ...")
            # SQL string for inserting data
            insert_sql = get_insert(table, header)

    # commit rows to database
    print ("Committing rows to database ...")
    db.commit()
    print ("Done!")



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Automatically insert CSV contents into MySQL')
    parser.add_argument('--table', dest='table', help='Set the name of the table. If not set the CSV filename will be used')
    parser.add_argument('--database', dest='database', default=os.environ['MYSQL_DATABASE'], help='Set the name of the database. If not set the test database will be used')
    parser.add_argument('--user', dest='user', default=os.environ['MYSQL_USER'], help='The MySQL login username')
    parser.add_argument('--password', dest='password', default=os.environ['MYSQL_PASSWORD'], help='The MySQL login password')
    parser.add_argument('--host', dest='host', default=os.environ['MYSQL_CONTAINER_NAME'], help='The MySQL host')
    parser.add_argument('input_file', help='The input CSV file')
    args = parser.parse_args(sys.argv[1:])
    if not args.table:
        # use input file name for table
        args.table = os.path.splitext(os.path.basename(args.input_file))[0]

    main(args.input_file, args.user, args.password, args.host, args.table, args.database)

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "WebApp.settings.local")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

Even though I am able to read my csv file and import , it is throwing error for one particular table ie 即使我能够读取我的csv文件并导入,它也会丢失一个特定的表,即

DROP TABLE IF EXISTS `param_system`;
CREATE TABLE `param_system` (
`ID` int(11) NOT NULL,
  `EXTERNAL_EDIT` int(11) DEFAULT '0',
  `INTERNAL_EDIT` int(11) DEFAULT '0',
  `FORTRAN_TYPE` varchar(50) DEFAULT NULL,
  `LABEL` varchar(255) DEFAULT NULL,
  `DESCRIPTION` varchar(255) DEFAULT NULL,
  `HELP_ID` int(11) DEFAULT '0',
  `HELP_TEXT` text DEFAULT NULL,
  `GROUPNAME` varchar(255) DEFAULT NULL,
  `ROWNUM` int(11) DEFAULT '0',
  `WIDGET` varchar(50) DEFAULT NULL,
  `OPTIONS` varchar(255) DEFAULT NULL,
  `DISABLED` int(11) DEFAULT '0',
  `READONLY` int(11) DEFAULT '0',
  `REQUIRED` int(11) DEFAULT '0',
  `UI` text DEFAULT NULL,
  `MIN_VALUE` varchar(50) DEFAULT NULL,
  `MAX_VALUE` varchar(50) DEFAULT NULL,
  `FORM_VAR_NAME` varchar(255) DEFAULT NULL,
  `PARAM` varchar(255) DEFAULT NULL,
  `VAL` varchar(255) DEFAULT NULL,
  `DEFAULT` varchar(255) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8;

The error ie being thrown is: 抛出的错误是:

_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default) VALUES ('5', '0', '0', 'integer', '', '', '1', '', 'Base Parameters', '' at line 1") _mysql_exceptions.ProgrammingError:(1064,“你的SQL语法有错误;请查看与你的MySQL服务器版本相对应的手册,以便在'default'附近使用正确的语法)VALUES('5','0','0' ,'整数','','','1','','基本参数',''在第1行“)

Below is the screen shot of the csv that I am trying to import: 下面是我要导入的csv的屏幕截图: param_system.csv

As you can see that it is not able to read the number "1" after "Base Parameters" and throwing the error. 正如您所看到的,它无法在“基本参数”之后读取数字“1”并抛出错误。 Could someone help me with what is going wrong? 有人可以帮我解决出错的问题吗?

_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'default) VALUES ('5', '0', '0', 'integer', '', '', '1', '', 'Base Parameters', '' at line 1") _mysql_exceptions.ProgrammingError:(1064,“你的SQL语法有错误;请查看与你的MySQL服务器版本相对应的手册,以便在'default'附近使用正确的语法)VALUES('5','0','0' ,'整数','','','1','','基本参数',''在第1行“)

What you are seeing is a fragment of an INSERT statement. 您看到的是INSERT语句的片段。 It isn't showing you the whole INSERT statement, it cuts it off. 它没有向您显示整个INSERT语句,它将其切断。 You said you think it is not reading the '1' in the ROWNUM field of your input data, but you are misinterpreting the error message. 你说你认为它不是在输入数据的ROWNUM字段中读取'1',但是你误解了错误信息。

It's just a coincidence that you see two single-quotes next to each other in the error message. 您在错误消息中看到彼此相邻的两个单引号只是巧合。 The error message is formatted like this: 错误消息的格式如下:

_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '...' at line 1") _mysql_exceptions.ProgrammingError:(1064,“您的SQL语法中有错误;请查看与您的MySQL服务器版本对应的手册,以便在第1行的'...'附近使用正确的语法”)

Where ... will be a fragment of the long SQL statement, starting with the first token that confused the parser, and continuing in this case for 80 characters. where ...将是长SQL语句的一个片段,从混淆解析器的第一个令牌开始,在这种情况下继续80个字符。 This 80-character fragment is: 这个80个字符的片段是:

default) VALUES ('5', '0', '0', 'integer', '', '', '1', '', 'Base Parameters', '

It's purely by accident that the 80th character is a single-quote, and then the next character in the error message is also a single-quote. 纯粹是偶然的,第80个字符是单引号,然后错误消息中的下一个字符也是单引号。 It is not an empty string in place of the value '1' you expected to be read from the input. 它不是一个空字符串,而是'1'您希望从输入中读取的值'1' In fact, I assume it is reading the data value from the input. 实际上,我假设它正在从输入中读取数据值。

So the problem reported in the error is that you're using the SQL reserved word DEFAULT as a column name. 因此,错误中报告的问题是您使用SQL保留字 DEFAULT作为列名。 This Python script is not delimiting it. 这个Python脚本没有分隔它。 So the appearance of the reserved word in the INSERT statement confuses the parser. 因此,INSERT语句中保留字的出现会混淆解析器。

I believe you can fix this in the Python script by formatting the column names inside back-ticks in the INSERT statement: 我相信你可以通过在INSERT语句中格式化back-ticks中的列名来在Python脚本中解决这个问题:

def get_insert(table, header):
    """Generate the SQL for inserting rows
    """
    field_names = ', '.join('`%s`' % col for col in header)
    field_markers = ', '.join('%s' for col in header)
    return 'INSERT INTO %s (%s) VALUES (%s);' % \
        (table, field_names, field_markers)

You could alternatively edit your input CSV file to avoid using SQL reserved words in the column names defined in the header. 您也可以编辑输入CSV文件,以避免在标题中定义的列名中使用SQL保留字。

@BillKarwin, When I used Django admin page to see the same table that was loaded in mysql db (after it was modified to take DEFAULT as a field name), it was throwing the "string index out of range" error. @BillKarwin,当我使用Django管理页面查看在mysql db中加载的同一个表(在修改为将DEFAULT作为字段名称后)时,它抛出了“字符串索引超出范围”错误。 I couldn't pinpoint to the exact location where it is throwing the error. 我无法确定它抛出错误的确切位置。 Is it because of the len(header) code in the main function? 是因为main函数中的len(header)代码? SS_1 SS_2

暂无
暂无

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

相关问题 1064(42000):您的 SQL 语法有错误; 检查与您的 MySQL 服务器版本相对应的手册,以获取正确的语法使用 - 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use 您的 SQL 语法有错误; 检查与您的 MySQL 服务器版本相对应的手册,以获取在 &#39;) 附近使用的正确语法 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') “你的SQL语法有错误; 查看与您的MySQL服务器版本对应的手册,以便在&#39;&#39;第1行&#39;附近使用正确的语法 - “You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1” 警告:您的SQL语法有错误; 查看与您的MySQL服务器版本对应的手册,以便在附近使用正确的语法 - Warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 您的 SQL 语法有错误; 检查与您的 MySQL 服务器版本相对应的手册,以获取在 \'keyword")\' 附近使用的正确语法 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'keyword")\' 您的 SQL 语法有错误; 检查与您的 MySQL 服务器版本相对应的手册,以获取在 '*) 附近使用的正确语法 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*) 修复“查看与您的 MySQL 服务器版本相对应的手册,以获取在 '%s 附近使用的正确语法” - FIX “Check the manual that corresponds to your MySQL server version for the right syntax to use near '%s” 您的SQL语法有错误; 检查与您的MariaDB服务器版本对应的手册,以便在第1行附近使用正确的语法, - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near at line 1", _mysql_exceptions.ProgrammingError:(1064,“您的SQ L语法有错误;在第1行的&#39;)&#39;附近使用了正确的语法”) - _mysql_exceptions.ProgrammingError: (1064, “You have an error in your SQ L syntax; right syntax to use near ')' at line 1”) MYSQL 数据库错误:“pymysql.err.ProgrammingError: (1064, ”您的 SQL 语法有错误;请查看与您对应的手册-" - MYSQL Database error: “pymysql.err.ProgrammingError: (1064, ”You have an error in your SQL syntax; check the manual that corresponds to your-"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM