我在SQL Server 2017中使用Python .Python代码包含在我传递查询的存储过程中。查询得到评估,数据传递给Python。如果查询中的字符串列(char,nchar,varchar,nvarchar)包含NULL
,则它将在Python中映射到None
。但如果int
列包含NULL
,则会将其映射到-2147483648
(我猜最小整数值)。
我的问题是如何在NULL
列中将int
值设为None
,而不是-2147483648
?该列需要保留int
。
我正在使用的测试数据:
CREATE TABLE [dbo].[test_table](
[a-string] [nvarchar](50) NULL,
[a-date] [date] NULL,
[a-int] [int] NULL,
[a-null-int] [int] NULL,
[a-null-str] [nvarchar](50) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[test_table] ([a-string], [a-date], [a-int], [a-null-int], [a-null-str]) VALUES (N'asdf', CAST(N'2018-04-11' AS Date), 1, NULL, NULL)
INSERT [dbo].[test_table] ([a-string], [a-date], [a-int], [a-null-int], [a-null-str]) VALUES (N'fdsa', CAST(N'2008-04-11' AS Date), 2, NULL, NULL)
INSERT [dbo].[test_table] ([a-string], [a-date], [a-int], [a-null-int], [a-null-str]) VALUES (N'Bob "Bla" Bob', CAST(N'2028-04-11' AS Date), 3, NULL, NULL)
INSERT [dbo].[test_table] ([a-string], [a-date], [a-int], [a-null-int], [a-null-str]) VALUES (N'Bob, Bob', CAST(N'2038-04-11' AS Date), 4, NULL, NULL)
INSERT [dbo].[test_table] ([a-string], [a-date], [a-int], [a-null-int], [a-null-str]) VALUES (N'Bob bob', CAST(N'1998-04-11' AS Date), 5, 1, NULL)
最后两列包含一些NULL
值。第一个类型为int
,第二个类型为nvarchar
。
存储过程的代码:
CREATE PROCEDURE [dbo].[usp_test]
@query NVARCHAR(max)
AS
BEGIN
EXEC sp_execute_external_script
@language = N'Python',
@script = N'
print(InputDataSet)
',
@input_data_1 = @query
END;
存储过程有一个带有查询的参数,该查询将查询结果传递给Python代码。在Python代码中我打印数据。
我如何执行存储过程:
EXEC [dbo].[usp_test] N'SELECT [a-string],CAST([a-date] as nvarchar(20)) as [a-date],[a-int],[a-null-int],[a-null-str] FROM [dbo].[test_table]'
结果是:
a-string a-date a-int a-null-int a-null-str 0 asdf 2018-04-11 1 -2147483648 None 1 fdsa 2008-04-11 2 -2147483648 None 2 Bob "Bla" Bob 2028-04-11 3 -2147483648 None 3 Bob, Bob 2038-04-11 4 -2147483648 None 4 Bob bob 1998-04-11 5 1 None
意外行为位于a-null-int
列中。在None
逗留期间,如何将其设为-2147483648
而不是int
?
这个问题与SQL Server密切相关。根据Microsoft的this documentation,BxlServer或SQL Satellite(不确定)处理SQL Server和Python之间的数据传输。我希望问题出在其中一项服务中。但我不知道如何规避它。
NA
:http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na IMO没有。似乎问题是数据类型之间存在差异(str vs int)。这不是这种情况。如果我检查数据类型,我得到:
print(type(InputDataSet.ix[0,"a-null-int"]))
>>> <class 'numpy.int32'>
这是对的。我正在传递int
列,并将其映射到python int
。但我需要的是None
。
在开始之前,我需要说明[a-null-int]
列需要保持整数类型。对于上下文,我需要将数据导出为CSV。为了说明我的问题,我将[a-null-int]
列中最后一行的值从NULL
更改为1
。相应地改变了问题的开头。
使用RxMissingValues.int32()
,我得到用于替换NULL
值的值,即-2147483648
。我可以用numpy.NaN
替换这些值。它不是防弹修复,因为如果SQL Server中的列包含这个值会发生什么?然而,我继续走这条路......
我在上面的存储过程中输入了以下代码:
import numpy
from revoscalepy import RxMissingValues
InputDataSet.loc[InputDataSet["a-null-int"] == RxMissingValues.int32(), ("a-null-int")] = numpy.NaN
print(InputDataSet)
这是我的(缩写):
a-null-int 0 NaN 1 NaN 2 NaN 3 NaN 4 1.0
[a-null-int]
列转换为float
。 pandas doc中记录了此行为,并已在stackoverflow上进行了讨论。
由于处理NA
值的NumPy限制,我希望我的问题无法解决。我还会再等一下,看看是否有更多的答案可以告诉我如何将列a-null-int
的类型保持为int
,或者一些解决方法。否则我会接受@ arun-gurunathan回答。
答案 0 :(得分:1)
rxMissingValues document描述了在整数列中存储None值的pandas / numpy限制。您可以通过检查缺失值(rxMissingValues.int32())来处理这些问题,如文档中所述。