数据框数据插入 MySQL 表后的架构更改

Posted

技术标签:

【中文标题】数据框数据插入 MySQL 表后的架构更改【英文标题】:Schema Changes after Dataframe Data insert into MySQL Table 【发布时间】:2018-05-21 10:36:26 【问题描述】:

我是 Spark SQL 的新手,

我正在使用 DataFrame,其架构如下

fields.add(DataTypes.createStructField(fieldName[0], DataTypes.StringType, true));
fields.add(DataTypes.createStructField(fieldName[1], DataTypes.StringType, true));
fields.add(DataTypes.createStructField(fieldName[2], DataTypes.DoubleType, true));
fields.add(DataTypes.createStructField(fieldName[3], DataTypes.StringType, true));

我正在将数据覆盖到 mysql 中,MySQL Schema 如下所示。

Field[0], VARCHAR(20)
Field[1], VARCHAR(20)
Field[2], DOUBLE
Field[3], DATETIME

每当数据写入 MySQL 表时,它都会将架构覆盖为 Text、Text、Double、Text。

我不想改变架构,它应该插入数据而不改变MySQL中表的架构,请建议。

我使用的是 spark-core_2.10 1.6 版、spark-sql_2.10 1.6 版

我尝试过转换值但没有成功

DataFrame intoSql;
intoSql.selectExpr("cast(Field1 as java.sql.Types.VARCHAR) Field1");
intoSql.selectExpr("cast(Field2 as java.sql.Types.VARCHAR) Field2");
intoSql.selectExpr("cast(Field3 as java.sql.Types.TIMESTAMP) Field3");
intoSql.write().format("TableNameinMYSQL").mode(SaveMode.Overwrite).jdbc(url, tableName, Properties);

【问题讨论】:

【参考方案1】:

你应该设置truncate option

truncate (default false): 使用 TRUNCATE TABLE 而不是 DROP TABLE。

如果发生故障,用户应关闭 truncate 选项以再次使用 DROP TABLE。此外,由于 DBMS 中 TRUNCATE TABLE 的行为不同,使用它并不总是安全的。 MySQLDialect、DB2Dialect、MsSqlServerDialect、DerbyDialect 和 OracleDialect 支持这一点,而 PostgresDialect 和默认的 JDBCDirect 不支持。对于未知且不受支持的 JDBCDirect,将忽略用户选项 truncate。 给true

intoSql.write()
  .option("truncate", "true")
  .mode(SaveMode.Overwrite)
  .jdbc(url, tableName, Properties);

【讨论】:

感谢您的帮助,即使在使用 .option("truncate", "true") 之后,MySQL 的模式已经从 Field1,varchar(20) Field2,varchar(20) Field3,double Field4, datetime to Field1, Text Field2, Text Field3, double Field4, Text 也许这是/现在是您使用的 Spark 版本中的错误。我在使用 Spark 2.2.0 时遇到了同样的问题,而在使用 Spark 2.3.1 时,这个选项确实有效。【参考方案2】:

也许您可以尝试使用 MetadataBuilder 和 createTableColumnTypes 属性,如本测试用例 https://github.com/apache/spark/blob/master/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCWriteSuite.scala#L454 所示?

【讨论】:

以上是关于数据框数据插入 MySQL 表后的架构更改的主要内容,如果未能解决你的问题,请参考以下文章

[更新mysql表后仅在单个列中丢失数据

您能否在视图上编写触发器,该视图在更改其基表后利用插入和删除表中的数据?

“创建目标表后架构已更改”错误如何发生?

捕获mssqlservice 修改表后的数据,统一存储到特定的表中,之后通过代码同步两个库的数据

解决MySQL向表中增加数据插入中文乱码问题

从数据库中删除所有表后,如何将 prisma 重新部署到数据库