MYSQL LOAD DATA INFILE 语句适用于工作台,但不适用于 python

鲍勃·迪尔

我正在使用房利美抵押贷款数据试验 MySQL 和数据分析。为此,我创建了两个表(“perf”和“acq”)和几个 python 函数。我首先删除集合和表(如果存在),然后创建集合(mortgage_analysis)和两个表。然后我建立一个文件列表,这些文件对应于我想要执行的分析年数。所有这些都很好。

然后,我使用以下函数将表格中的数据加载到来自房利美的 perf 和 acq 文本文件中。相同的函数用于加载两个表。它每次都与“perf”表一起工作,而从不与“acq”表一起工作。如果我获取 SQL 语句并在 mySQL 工作台中执行它们,则这些语句每次都有效。我很难过,可以使用一些帮助。

在工作台中有效但在 Python 中无效的 SQL 语句是:

LOAD DATA  INFILE '/Users/<my user name>/github/mortgage-analysis-example/data/text/acq/Acquisition_2000Q1.txt' 
INTO TABLE acq 
FIELDS TERMINATED BY '|' 
LINES TERMINATED BY '\n' 
(loan_id, orig_channel, seller_name, orig_interest_rate, orig_upb, orig_loan_term, 
 orig_date, first_pay_date, orig_ltv, orig_cltv, num_borrowers, dti, 
 borrower_credit_score, first_home_buyer, loan_purpose, property_type, num_units, 
 occupancy_status, property_state, zip, mortgage_insurance_percent, product_type, 
 coborrow_credit_score, mortgage_insurance_type, relocation_mortgage_ind);

加载这个的python函数是:

def loadTable(env_in, template, file_list):
    # env_in: (i know, uck global variable, holds info for this notebook common to all functions
    # template: SQL template file
    # file_list: python list element with fully qualified file names to use with SQL statement 
    env = env_in # environment info
    from mysql.connector import Error
    _file = open(env["base_path"]+env["path_separator"]+template, "r")
    _template = _file.readlines()
    try:
        conn = mysql.connector.connect(host=env["mySQL"]["host"],user=env["mySQL"]["user"], passwd=env['pw'])
        if conn.is_connected():
            print('Connected to MySQL database')
    except Error as e:
            print(e)
    cursor = conn.cursor()
    cursor.execute("USE mortgage_analysis;")
    cursor.execute("SET SESSION sql_mode = '';")
    print("starting table load")
    t0 = time.time()
    res = []
    for _file in file_list:
        _sql = _template[0].format(_file)
        print(f"\n{_sql}\n")
        try:
            res = cursor.execute(_sql)
            warn = cursor.fetchwarnings()
            #print(f"warn: {warn}")
        except Error as e:
            print(f"{_sql} \n{e}")

    t1 = time.time()
    print(f"Years: {env['years']} Table load time: {t1-t0}") 
    conn.close
    return env

没有发现错误(try 总是有效),也没有产生警告(fetchwarnings 总是空的)。

用于创建这两个表的 SQL 语句是:

DROP TABLE IF EXISTS acq;
CREATE TABLE acq (id DOUBLE AUTO_INCREMENT, loan_id DOUBLE, orig_channel VARCHAR(255), seller_name VARCHAR(255), orig_interest_rate DOUBLE, orig_upb DOUBLE, orig_loan_term DOUBLE, orig_date VARCHAR(255), first_pay_date VARCHAR(255), orig_ltv DOUBLE, orig_cltv DOUBLE, num_borrowers DOUBLE, dti DOUBLE, borrower_credit_score DOUBLE, first_home_buyer VARCHAR(255), loan_purpose VARCHAR(255), property_type VARCHAR(255), num_units DOUBLE, occupancy_status VARCHAR(255), property_state VARCHAR(255), zip DOUBLE, mortgage_insurance_percent DOUBLE, product_type VARCHAR(255), coborrow_credit_score DOUBLE, mortgage_insurance_type DOUBLE, relocation_mortgage_ind VARCHAR(255), PRIMARY KEY (id));
DROP TABLE IF EXISTS perf;
CREATE TABLE perf (id DOUBLE AUTO_INCREMENT, loan_id DOUBLE, monthly_reporting_period VARCHAR(255), servicer VARCHAR(255), interest_rate DECIMAL(6,3), current_actual_upb DECIMAL(12,2), loan_age DOUBLE, remaining_months_to_legal_maturity DOUBLE, adj_remaining_months_to_maturity DOUBLE, maturity_date VARCHAR(255), msa DOUBLE, current_loan_delinquency_status DOUBLE, mod_flag VARCHAR(255), zero_balance_code VARCHAR(255), zero_balance_effective_date VARCHAR(255), last_paid_installment_date VARCHAR(255), foreclosed_after VARCHAR(255), disposition_date VARCHAR(255), foreclosure_costs DOUBLE, prop_preservation_and_reair_costs DOUBLE, asset_recovery_costs DOUBLE, misc_holding_expenses DOUBLE, holding_taxes DOUBLE, net_sale_proceeds DOUBLE, credit_enhancement_proceeds DOUBLE, repurchase_make_whole_proceeds DOUBLE, other_foreclosure_proceeds DOUBLE, non_interest_bearing_upb DOUBLE, principal_forgiveness_upb VARCHAR(255), repurchase_make_whole_proceeds_flag VARCHAR(255), foreclosure_principal_write_off_amount VARCHAR(255), servicing_activity_indicator VARCHAR(255), PRIMARY KEY (id));
比尔·卡尔文

我测试了代码,我必须进行一些更改才能使其正常工作。

不要改变sql_mode我没有收到任何错误,我能够在不影响 sql_mode 的情况下加载数据。

我使用了测试数据:

1|2|name1|3|4|4|date|date|5|6|7|8|9|buyer|purpose|type|10|status|state|11|12|type|13|14|ind
1|2|name2|3|4|4|date|date|5|6|7|8|9|buyer|purpose|type|10|status|state|11|12|type|13|14|ind

我敦促您选择更合适的数据类型。您应该在 MySQL 中几乎从不使用 FLOAT 或 DOUBLE,除非您要存储科学测量值或其他东西。绝对不是货币单位或整数。

我不会使用 VARCHAR 来存储日期。MySQL 有 DATE 和 DATETIME,它们确保日期格式正确,因此您可以进行比较、排序、日期算术等。

如果您有错误提示您应该放宽 sql_mode 并允许无效查询或无效数据,我建议您改为修复数据。即使您加载了数据,如果您允许非严格的 SQL 模式,也有可能成为垃圾。

代码更改:

我没有使用format()尝试将文件名插入到查询模板中,而是使用了查询参数。删除带有 的行_template[0].format(_file),改为使用:

res = cursor.execute(_template, [_file])

但是模板必须在不带引号的情况下放置占位符:

正确的:

LOAD DATA INFILE %s INTO TABLE...

不正确:

LOAD DATA INFILE '%s' INTO TABLE...

最后,默认情况下不提交 Python 中的数据更改。也就是说,您可以插入数据,然后在使用时conn.close将未提交的更改丢弃。所以我加了一行:

conn.commit()

try/catch我在执行 SQL 后将其放入块中。

这样就成功加载了数据。请注意,我必须对您的输入数据做出假设,因为您没有共享样本。我不知道您的文件是否实际上具有正确的字段分隔符和行分隔符。但我认为它是,因为你说它在 MySQL Workbench 中工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

MySQL / Python LOAD DATA LOCAL INFILE错误

LOAD DATA INFILE MYSQL错误

MySQL LOAD DATA INFILE存储行号

MYSQL LOAD DATA INFILE 正确的文件路径

MySQL:启用LOAD DATA LOCAL INFILE重置

MySQL 5.7.26 不接受 \N 用于使用 Load Data Infile 的可为空的 int 列

PESSIMESTIC LOCK不适用于Spring Data访问MySQL

当csv表标题与mySQL表标题不匹配时,使用LOAD DATA INFILE语句吗?

MySQL查询适用于SELECT,但不适用于UPDATE语句

Python MySQL连接器不适用于SSL

MySQL LOAD DATA LOCAL INFILE不允许通过ODBC

mysql LOAD DATA LOCAL INFILE找不到文件

Pi 上的 MySQL LOAD DATA INFILE 错误 13

mysql LOAD DATA INFILE NA转换为NULL

MySQL:LOAD DATA INFILE 产生不正确的表结果

MySQL:LOAD DATA INFILE csv 忽略主字段插入

没有字段终止的mysql LOAD DATA INFILE

MySQL LOAD DATA INFILE数据太长而导致列异常

BASH如何等待mysql LOAD DATA LOCAL INFILE完成

Mysql'LOAD DATA LOCAL INFILE'根据文件指定列的值

加载数据到mysql LOAD DATA INFILE 难度

MySQL LOAD DATA INFILE查询成功运行但没有输出

LOAD DATA LOCAL INFILE卡住

工作两年后,突然在 LOAD DATA LOCAL INFILE 上出现 MYSQL“格式错误的数据包”

maplotlib.pyplot.show() 适用于 python 但不适用于 jupyter 控制台

DATA INFILE和LOAD DATA LOCAL INFILE之间的区别

查询适用于 Windows 上的 MySQL,但不适用于 Ubuntu 上的 Mysql

bigquery python 客户端:load_table_from_file 不适用于 csv 文件

适用于Python 2但不适用于Python 3的Python子进程PIPE