MySQL BIGINT 插入不一致?

问题描述

在 ubuntu.. 上运行 MysqL v 5.6。 创建了一个执行我所有操作的 python 程序。

我的应用程序动态创建表。有许多。一些非常相似..例如,这里有两个:

create table tst.intgn_party_test_load (
  party_id bigint unsigned NOT NULL,party_supertype varchar(15) NOT NULL,carrier_party_id bigint unsigned NOT NULL,full_name varchar(500),lda_actv_ind integer,lda_file_id integer,lda_created_by varchar(100),lda_created_on datetime,lda_updated_by varchar(100),lda_updated_on datetime,PRIMARY KEY(party_id,party_supertype,carrier_party_id)
) 

create table tst.intgn_party_relationship (
  parent_party_id bigint unsigned NOT NULL,child_party_id bigint unsigned NOT NULL,relationship_type varchar(10),PRIMARY KEY(parent_party_id,child_party_id,relationship_type)
) 

我的程序还动态填充表格。我使用转换为 BIGINT 的源数据构建派对 ID 字段。 例如,它为第一个表构造的插入是:

INSERT INTO intgn_party_test_load (
  party_supertype,carrier_party_id,party_id,full_name,lda_actv_ind,lda_file_id) 
SELECT  
  'Agency' as s0,0 as s1,CONV(SUBSTRING(CAST(SHA(CONCAT(full_name,ga)) AS CHAR),1,16),16,10) as s2,CONCAT(full_name,'-',ga) as s3,lda_file_id 
FROM tst.raw_listing_20210118175114 
ON DUPLICATE KEY 
UPDATE  
  full_name = VALUES(full_name),lda_actv_ind = VALUES(lda_actv_ind),lda_file_id = VALUES(lda_file_id) ;

对于第二个表,插入构造看起来非常相似,并且基于完全相同的源数据:

INSERT INTO tst.intgn_party_relationship (
  parent_party_id,relationship_type,lda_file_id) 
SELECT (Select party_id 
        from intgn_party 
        where full_name = 'xxx') as s0,'Location' as s1,lda_file_id 
FROM tst.raw_listing_20210118175114 
ON DUPLICATE KEY 
UPDATE  
  lda_actv_ind = VALUES(lda_actv_ind),lda_file_id = VALUES(lda_file_id) 

现在...第一个表 (intgn_party_test_load) 是问题所在。我可以删除它,甚至手动重新创建它……无论我做什么,通过 python 插入的数据都将 BIGINT party_id 截断为 16 位数字。 使用完全相同的公式填充 party_id 的每个其他 TABLE 创建长度在 18 到 20 位之间的 BIGINT 数字。我可以看到表中加载的所有相同的源记录,并且我看到第一个表 (intgn_party_test_load) 中的截断值。例如,第一个表有一个记录,party id = 7129232523783260。第二个表(和许多其他表)有相同的记录,加载了 [child]party id = 7129232523783260081

完全相同的公式,从 python 中以完全相同的方式执行.. 但是这个表得到了更短的 BIGINT。

有趣的是,我尝试手动将插入运行到该表中(不使用 python 程序),它插入了完整的 BIGINT 值。 所以我很困惑为什么 python 程序“选择”这个表不能正常工作,而它在所有其他表上工作正常。

是否存在值被截断的奇怪情况? 顺便说一句,我的 python 程序利用 sqlalchemy 来运行创建/插入。由于它是手动工作的,我必须假设它与 sqlalchemy 相关。

[编辑] 添加,通过 sqlalchemy 的 sql 命令使用 db_connection.execute(sql)

执行

[编辑 - 添加更多代码细节]

from sqlalchemy import create_engine,exc

engine = create_engine(
            connection_string,pool_size=6,max_overflow=10,encoding='latin1',isolation_level='AUTOCOMMIT'
        )
        connection = engine.connect()

sql = "INSERT INTO intgn_party_test_load (
  party_supertype,lda_file_id = VALUES(lda_file_id) ;"

        result = db_connection.execute(sql)

那是我也可以减少它的最好方法代码要复杂得多,因为它动态地创建了其他事情的语句)..但是从我的日志记录中,我看到了它正在执行的确切语句(如上所述),并且我之后在 BIGINT 列中查看结果。除了这张桌子以外的所有桌子。并且仅当通过应用程序时。 所以即使通过应用程序也不会发生在其他表上..

非常令人困惑.. 希望有人知道 MysqL 5.6 中关于 BIGINT 的错误,因为它可能与目标表的键构造或记录的总长度有关.. 或其他一些疯狂的原因。有趣的是,我确实看到了这一点,如果我在长度大于 18 位的 BIGINT 列上执行不同的操作,它会返回为 16 位 - 猜测不同的函数不支持 BIGINT .. 有点希望这暗示了一个问题,但我不明白为什么其他表可以正常工作......

[编辑 - 添加一些我看到 sqlalchemy 显然正在运行的东西,围绕我的查询的实际运行......只是在疯狂的情况下它们会影响任何东西 - 对于一张表?? ]

SET AUTOCOMMIT = 0
SET AUTOCOMMIT = 1
SET NAMES utf8mb4
SHOW VARIABLES LIKE 'sql_mode'
SHOW VARIABLES LIKE 'lower_case_table_names'
SELECT VERSION()
SELECT DATABASE()
SELECT @@tx_isolation
show collation where `Charset` = 'utf8mb4' and `Collation` = 'utf8mb4_bin'
SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
SELECT CAST('test collated returns' AS CHAR CHaraCTER SET utf8mb4) COLLATE utf8mb4_bin AS anon_1
ROLLBACK
SET NAMES utf8mb4

很难说顺序或类似的东西......有很多可以在同一微秒内运行。

解决方法

在绞尽脑汁数天之后......从各个角度来看,我无法弄清楚为什么很多表中有 1 个在截断 SHA 值时出现问题。 最后,我重新设计了我持有 Id 的方式,我不再费心转换为 BIGINT。当我将其保留为 CHAR 时,一切正常。

CAST(SHA(CONCAT(full_name,ga)) AS CHAR)

因此将我所有的 Id 列更改为 varchar(40) 并使用上述样式。现在一切都很好。联接将使用 varchar 而不是 bigint - 我可以接受。