如何防止 SQL 服务器在导入数据时去除前导零
How to prevent SQL Server from stripping leading zeros when importing data
A data file
导入到 SQL Server
table。数据文件中的一列是文本数据类型,该列中的值仅为整数。 SQL 服务器数据库中目标 table 中的相应列的类型为 varchar(100)
。但是在数据导入之后,SQL 服务器将 0474525431
等值存储为 4.74525431E8
即 Scientific Notations
.
问题: 在上述情况下,我们如何防止SQL 服务器将值存储到Scientific Notations
。例如,当 0474525431
被插入到 VARCHAR(100)
列时,它应该按原样存储而不是 4.74525431E8
更新:
导入数据的代码:
from pyspark.sql.functions import *
df = spark.read.csv(".../Test/MyFile.csv", header="true", inferSchema="true")
server_name = "jdbc:sqlserver://{SERVER_ADDR}"
database_name = "database_name"
url = server_name + ";" + "databaseName=" + database_name + ";"
table_name = "table_name"
username = "username"
password = "myPassword"
try:
df.write \
.format("com.microsoft.sqlserver.jdbc.spark") \
.mode("overwrite") \
.option("url", url) \
.option("dbtable", table_name) \
.option("user", username) \
.option("password", password) \
.save()
except ValueError as error :
print("Connector write failed", error)
更新2:
这个问题似乎也与前导零有关。我创建了一个示例文件(如下所示)并将其数据导入相应的 SQL table(也如下所示),并注意到前导零已被删除。尽管数据文件中的所有 6 列和 table 都是文本 (varchar):
,但这种情况仍在发生
数据文件:
Col1|Col2|Col3|Col4|Col5|Col6
abc|12345|Y|0123456789|D|Test
xyz|54321|Y|0123456789|D|Test
rst|67891|Y|0123456789|D|Test
uvw|65432|Y|0123456789|D|Test
Table数据导入后:
Spark 正在推断架构,它正在为包含值“0474525431”的列选择 integer
。因此,当读取 DataFrame 时,该值将转换为整数并丢弃前导零。
因此您需要确保 DataFrame 具有正确的类型。您可以在创建 DataFrame 时明确指定模式,或者关闭 inferSchema
然后将选定的列转换为不同的类型,然后再加载到 SQL 服务器。两者的例子都在 .
中
这是一个示例,显示如果 DataFrame 使用 string
列而不是 integer
列,则会保留前导“0”。
from pyspark.sql.functions import *
jdbcUrl = "jdbc:sqlserver://{0}:{1};database={2}".format(jdbcHostname, jdbcPort, jdbcDatabase)
connectionProperties = {
"user" : jdbcUsername,
"password" : jdbcPassword,
"driver" : "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}
pushdown_query = "(select '0474525431' f, * from sys.objects) emp"
df = spark.read.jdbc(url=jdbcUrl, table=pushdown_query, properties=connectionProperties)
df.write.mode("overwrite").option("header",True).csv("datalake/temp.csv")
df = spark.read.csv("datalake/temp.csv", header="true", inferSchema="false")
df.printSchema()
table_name = "table_name"
try:
df.write \
.format("com.microsoft.sqlserver.jdbc.spark") \
.mode("overwrite") \
.option("url", jdbcUrl) \
.option("dbtable", table_name) \
.option("user", jdbcUsername) \
.option("password", jdbcPassword) \
.save()
except ValueError as error :
print("Connector write failed", error)
df = spark.read.jdbc(url=jdbcUrl, table=table_name, properties=connectionProperties)
display(df)
A data file
导入到 SQL Server
table。数据文件中的一列是文本数据类型,该列中的值仅为整数。 SQL 服务器数据库中目标 table 中的相应列的类型为 varchar(100)
。但是在数据导入之后,SQL 服务器将 0474525431
等值存储为 4.74525431E8
即 Scientific Notations
.
问题: 在上述情况下,我们如何防止SQL 服务器将值存储到Scientific Notations
。例如,当 0474525431
被插入到 VARCHAR(100)
列时,它应该按原样存储而不是 4.74525431E8
更新:
导入数据的代码:
from pyspark.sql.functions import *
df = spark.read.csv(".../Test/MyFile.csv", header="true", inferSchema="true")
server_name = "jdbc:sqlserver://{SERVER_ADDR}"
database_name = "database_name"
url = server_name + ";" + "databaseName=" + database_name + ";"
table_name = "table_name"
username = "username"
password = "myPassword"
try:
df.write \
.format("com.microsoft.sqlserver.jdbc.spark") \
.mode("overwrite") \
.option("url", url) \
.option("dbtable", table_name) \
.option("user", username) \
.option("password", password) \
.save()
except ValueError as error :
print("Connector write failed", error)
更新2:
这个问题似乎也与前导零有关。我创建了一个示例文件(如下所示)并将其数据导入相应的 SQL table(也如下所示),并注意到前导零已被删除。尽管数据文件中的所有 6 列和 table 都是文本 (varchar):
,但这种情况仍在发生数据文件:
Col1|Col2|Col3|Col4|Col5|Col6
abc|12345|Y|0123456789|D|Test
xyz|54321|Y|0123456789|D|Test
rst|67891|Y|0123456789|D|Test
uvw|65432|Y|0123456789|D|Test
Table数据导入后:
Spark 正在推断架构,它正在为包含值“0474525431”的列选择 integer
。因此,当读取 DataFrame 时,该值将转换为整数并丢弃前导零。
因此您需要确保 DataFrame 具有正确的类型。您可以在创建 DataFrame 时明确指定模式,或者关闭 inferSchema
然后将选定的列转换为不同的类型,然后再加载到 SQL 服务器。两者的例子都在
这是一个示例,显示如果 DataFrame 使用 string
列而不是 integer
列,则会保留前导“0”。
from pyspark.sql.functions import *
jdbcUrl = "jdbc:sqlserver://{0}:{1};database={2}".format(jdbcHostname, jdbcPort, jdbcDatabase)
connectionProperties = {
"user" : jdbcUsername,
"password" : jdbcPassword,
"driver" : "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}
pushdown_query = "(select '0474525431' f, * from sys.objects) emp"
df = spark.read.jdbc(url=jdbcUrl, table=pushdown_query, properties=connectionProperties)
df.write.mode("overwrite").option("header",True).csv("datalake/temp.csv")
df = spark.read.csv("datalake/temp.csv", header="true", inferSchema="false")
df.printSchema()
table_name = "table_name"
try:
df.write \
.format("com.microsoft.sqlserver.jdbc.spark") \
.mode("overwrite") \
.option("url", jdbcUrl) \
.option("dbtable", table_name) \
.option("user", jdbcUsername) \
.option("password", jdbcPassword) \
.save()
except ValueError as error :
print("Connector write failed", error)
df = spark.read.jdbc(url=jdbcUrl, table=table_name, properties=connectionProperties)
display(df)