一些背景:目前我查询4Mio行(50列)从一个MS SQL服务器dbatools成PSObject(在批10.000行,每行查询),处理使用PowerShell(大量的正则表达式的东西)的数据回写成MariaDb和SimplySql。平均而言,我得到约。150行/秒 不得不使用很多技巧(Net的Stringbuilder等)来实现这一性能,它还不错,恕我直言
作为新要求,我想检测某些文本单元格的语言,并且必须删除个人数据(姓名和地址)。我为此找到了一些很好的python库(spacy和pycld2)。我用pycld2进行了测试-很好的检测。
简化代码以进行澄清(提示:我是python noob):
#get data from MS SQL
$data = Invoke-DbaQuery -SqlInstance $Connection -Query $Query -As PSObject -QueryTimeout 1800
for ($i=0;$i -lt $data.length;$i++){
#do a lot of other stuff here
#...
#finally make lang detection
if ($LangDetect.IsPresent){
$strLang = $tCaseDescription -replace "([^\p{L}\p{N}_\.\s]|`t|`n|`r)+",""
$arg = "import pycld2 as cld2; isReliable, textBytesFound, details = cld2.detect('" + $strLang + "', isPlainText = True, bestEffort = True);print(details[0][1])"
$tCaseLang = & $Env:Programfiles\Python39\python.exe -c $arg
} else {
$tCaseLang = ''
}
}
#write to MariaDB
Invoke-SqlUpdate -ConnectionName $ConnectionName -Query $Query
每次都可以执行此python调用,但是由于每次循环调用和导入pycld2 lib都会破坏性能(12行/秒)。因此,这是一个a脚的解决方案:)此外,如上所述-我想使用spacy-必须解析更多的列才能删除个人数据。
我不确定,是否愿意将整个PS Parser转换为python:|
我相信,更好的解决方案可能是将整个PSObject从PowerShell传递到python(在PS循环启动之前),然后将其以及PSObject(在python中进行处理后)返回,但我不知道如何用python / python函数实现这一点。
你的方法/建议是什么,还有其他想法?谢谢 :)
以下简化示例显示了如何将多个[pscustomobject]
([psobject]
)实例从PowerShell传递到Python脚本(-c
在这种情况下,通过字符串传递):
通过使用JSON作为序列化格式,通过ConvertTo-Json
...
...和顺便指出JSON经由管道,其Python可以经由读取标准输入(标准输入)。
重要事项:
字符编码:
$OutputEncoding
在将数据发送到外部程序(例如Python)时,PowerShell使用首选项变量中指定的编码,值得称赞的是,在PowerShell [Core] v6 +中,该默认值默认为无BOM的UTF-8 ,但在Windows PowerShell中,默认为ASCII(!)。
就像PowerShell的限制你发送文本到一个外部程序,它也不可避免地解释它接收文本,即基于存储在编码[Console]::OutputEncoding
; 遗憾的是,在撰写本文时,两个PowerShell版本均默认为系统的OEM代码页。
同时发送和接收(BOM-以下)UTF-8将在PowerShell的版本,(临时)组$OutputEncoding
和[Console]::OutputEncoding
如下:
$OutputEncoding = [Console]::OutputEncoding = [System.Text.Utf8Encoding]::new($false)
如果你希望Python脚本也输出对象,请再次考虑使用JSON,你可以在PowerShell上使用JSON将其解析为对象ConvertFrom-Json
。
# Sample input objects.
$data = [pscustomobject] @{ one = 1; two = 2 }, [pscustomobject] @{ one = 10; two = 20 }
# Convert to JSON and pipe to Python.
ConvertTo-Json $data | python -c @'
import sys, json
# Parse the JSON passed via stdin into a list of dictionaries.
dicts = json.load(sys.stdin)
# Sample processing: print the 'one' entry of each dict.
for dict in dicts:
print(dict['one'])
'@
如果要传递的数据是单行字符串的集合,则不需要JSON:
$data = 'foo', 'bar', 'baz'
$data | python -c @'
import sys
# Sample processing: print each stdin input line enclosed in [...]
for line in sys.stdin:
print('[' + line.rstrip('\r\n') + ']')
'@