86649


<https://pyorc.readthedocs.io/en/stable/tutorial.html#using-custom-converters>  
pyorc というモジュールのカスタムクラス内で

[code]

    class TestConverter(ORCConverter):
        @staticmethod
        def to_orc(obj, timezone):
          print(obj)
          print(type(obj))
          return (obj, 0)
    
[/code]

[code]

    1646092740
    <class 'int'>
    2022-03-02 13:21:12,888 [ERROR] Unable to cast Python instance to C++ type (compile in debug mode for details)
    
[/code]

というデバッグ出力とエラーになります

[code]

          return (int(obj), 0)
    
[/code]

とかくとエラーになりません

> [ERROR] Unable to cast Python instance to C++ type (compile in debug mode
> for details)

これはどういう意味のエラーなんでしょうか

元々 <class 'int'> なのに int(obj) でキャストすると何が変化するんでしょうか

* * *

再現できるデータを見極めたいんですがなかなか再現しません

エラーが再現するソースコード全体は後述のものになります

他のプログラムがシリアライズ化した marshal ファイルをもう１度よみこんでそのまま 中身を orc writer
に流し込むだけなのでデータに依存してるんだと思いますが、データの中身は業務情報が含まれていて公開できません

ただエラーになる直前のログは

[code]

    (1646200394,)
    1646200394
    <class 'int'>
    
[/code]

となるのでこの値を書き込んでエラーがでているのは間違い無いんですが  
コメントアウトしてる行を追加してこの値のみの１レコードを書き込んだファイルではエラーにならず成功します

[code]

    import datetime
    import pyorc
    import marshal
    from pyorc.converters import ORCConverter
    
    class TestConverter(ORCConverter):
      @staticmethod
      def to_orc(obj, timezone):
        print(obj)
        print(type(obj))
        return (obj, 0)
    
    # with open('test.msl', 'wb') as f:
    #   marshal.dump((1646200394,), f)
    
    with open('test.orc', 'wb') as orc_file:
      orc_writer = pyorc.Writer(
        orc_file,
        'struct<time:timestamp>',
        converters={pyorc.TypeKind.TIMESTAMP: TestConverter},
      )
      with open('test.msl', 'rb') as f:
        try:
          while True:
            row = marshal.load(f)
            print(row)
            orc_writer.write(row)
        except EOFError:
          pass
      
      orc_writer.close()
    
[/code]


CC BY-SA 4.0
2022-03-02T04:48:25.087
86640
2022-03-02T11:00:11.087
2022-03-02T10:00:10.193
question
python
int class なのに int() でキャストしないとエラーになる

[code]

      if not isinstance(obj, int)
        print(obj)
        print(type(obj))
    
[/code]

といれてみたところ float のデータが混ざっていました  
marshal データを作る側で python のデフォルトで datetime 型から timestamp() をよぶと float
になっちゃってたみたいです

ここからは想像ですが  
pyorc は列単位である程度データが溜まってからファイル出力するので  
write をよんでもすぐにかきこまれずに変換時になってもっと前に書き込んだ float を int 出力しようとしてエラーになったみたいです

お騒がせしました


CC BY-SA 4.0
2022-03-02T11:00:11.087
86649
2022-03-02T11:00:11.087
86640
answer