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

然后,我使用下面的函数将来自房利美的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 always works),也未生成警告(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_模式的情况下加载数据.

我使用了测试数据:

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

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

我不会用VARCHAR来存储日期.MySQL有DATE和DATETIME,它们确保了日期的格式良好,因此您可以进行比较、排序、日期算法等.

如果出现错误,建议您放松sql_模式,允许无效查询或无效数据,我建议您改为修复数据.即使加载了数据,如果允许非严格的SQL模式,数据也有变成垃圾的风险.

代码更改:

我没有使用format()来try 将文件名插入查询模板,而是使用了一个查询参数.删除带有_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()

在执行SQL之后,我将其放入try/catch块中.

这成功地加载了数据.注:我必须对您的输入数据进行假设,因为您没有共享样本.我不知道你的文件是否有正确的字段分隔符和行分隔符.但我想是的,因为你说它在MySQL Workbench中工作.

Mysql相关问答推荐

MySQL连接序列

MySQL-如何检测时间戳中的一天

MySQL-带有用户定义变量的IF-THEN语句

如何分解分组依据的数据?

mysqli 无法以非 root 用户身份连接

MYSQL:如何根据之前的相关记录获取记录

正则表达式模式相当于 mysql 中的 %word%

在 SQL 中将列添加为 End_date,间隔为 +100 天

更新和替换未加引号的 JSON 字符串

MySQL如何通过外键ID Select 多行?

为什么在有 BEGIN 和 END 时为存储过程指定分隔符?

MySQL中两个时间字段的分钟差

SQL UPDATE中的str_replace?

错误 1396 (HY000): 'user'@'localhost' 的操作 DROP USER 失败

Python MYSQL 更新语句

默认为空字符串的列

如何从两个不同的日期获得年份差异?

第 1 行的 CSV 输入中的列数无效错误

Sequelize:销毁/删除表中的所有记录

mysql 从日期格式中提取年份