<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">I have the filling that the CW 3.20.9
      machinery supports Binary fields.<br>
      We just need to restore the previous behavior of the
      '_create_copyfrom_buffer' function.<br>
      Here is quick test with my modifications in bold:<br>
      <br>
      <b>from psycopg2.extensions import Binary</b><br>
      <br>
      def _create_copyfrom_buffer(data, columns=None, **convert_opts):<br>
          """<br>
          Create a StringIO buffer for 'COPY FROM' command.<br>
          Deals with Unicode, Int, Float, Date... (see ``converters``)<br>
      <br>
          :data: a sequence/dict of tuples<br>
          :columns: list of columns to consider (default to all columns)<br>
          :converter_opts: keyword arguements given to converters<br>
          """<br>
          # Create a list rather than directly create a StringIO<br>
          # to correctly write lines separated by '\n' in a single step<br>
          rows = []<br>
          if columns is None:<br>
              if isinstance(data[0], (tuple, list)):<br>
                  columns = range(len(data[0]))<br>
              elif isinstance(data[0], dict):<br>
                  columns = data[0].keys()<br>
              else:<br>
                  raise ValueError('Could not get columns: you must
      provide columns.')<br>
          for row in data:<br>
              # Iterate over the different columns and the different
      values<br>
              # and try to convert them to a correct datatype.<br>
              # If an error is raised, do not continue.<br>
              formatted_row = []<br>
              for col in columns:<br>
                  try:<br>
                      value = row[col]<br>
                  except KeyError:<br>
                      warnings.warn(u"Column %s is not accessible in row
      %s"<br>
                                    % (col, row), RuntimeWarning)<br>
                      # XXX 'value' set to None so that the import does
      not end in<br>
                      # error.<br>
                      # Instead, the extra keys are set to NULL from the<br>
                      # database point of view.<br>
                      value = None<br>
      <b>            if isinstance(value, type(Binary(""))):</b><b><br>
      </b><b>                return None</b><br>
                  for types, converter in _COPYFROM_BUFFER_CONVERTERS:<br>
                      if isinstance(value, types):<br>
                          value = converter(value, **convert_opts)<br>
                          break<br>
                  else:<br>
                      raise ValueError("Unsupported value type %s" %
      type(value))<br>
                  # We push the value to the new formatted row<br>
                  # if the value is not None and could be converted to a
      string.<br>
                  formatted_row.append(value)<br>
              rows.append('\t'.join(formatted_row))<br>
          return StringIO('\n'.join(rows))<br>
      <br>
      Using a 'SQLGenObjectStore' I am then able to insert Binary
      fields.<br>
      Do you think such modification is valid and could be integrated in
      a future release?<br>
      <br>
      Antoine<br>
      <br>
      Le 04/12/2015 14:44, Rémi Cardona a écrit :<br>
    </div>
    <blockquote cite="mid:566198AF.6000904@logilab.fr" type="cite">Le
      04/12/2015 13:44, Antoine Grigis a écrit :
      <br>
      <blockquote type="cite">I noticed a change in the 'dataimport'
        module between CubicWeb (CW)
        <br>
        3.19.6 and CW 3.20.9.
        <br>
        The '_create_copyfrom_buffer' function has been refactored and
        the
        <br>
        default return case removed.
        <br>
        In the former version, the function default returned code was
        'None'.
        <br>
        This is catched in both CW versions by the
        '_execmany_thread_copy_from'
        <br>
        function in order to execute thread without 'copy from' tabular
        data
        <br>
        speedup.
        <br>
        <br>
        Thus in CW 3.20.9 inserting a 'Binray' entity field through the
        <br>
        'SQLGenObjectStore' raises an Exception.
        <br>
        <br>
        Is it a normal behavior? Is it still possible to insert a
        'Binary' field
        <br>
        using a store and a schema with inlined relations?
        <br>
      </blockquote>
      <br>
      Hi Antoine,
      <br>
      <br>
      The dataimport module was made stricter in CubicWeb 3.20 and newer
      releases. Its handling of binary objects is one such case.
      <br>
      <br>
      Do note that the current code (in 3.20 and all newer releases)
      relies on pyscopg2's copy_from() method [1] which only supports
      PostgreSQL's "text" format [2].
      <br>
      <br>
      AIUI, this "text" format cannot be used to deal with binary data,
      though we haven't given it much thought.
      <br>
      <br>
      If dealing with binary is possible, please let us know how.
      Patches will be greatly appreciated (even in an unfinished state).
      <br>
      <br>
      Cheers,
      <br>
      <br>
      Rémi
      <br>
      <br>
      [1]
      <a class="moz-txt-link-freetext" href="http://initd.org/psycopg/docs/usage.html#using-copy-to-and-copy-from">http://initd.org/psycopg/docs/usage.html#using-copy-to-and-copy-from</a>
      <br>
      [2]
      <a class="moz-txt-link-freetext" href="http://www.postgresql.org/docs/9.4/static/sql-copy.html#AEN71994">http://www.postgresql.org/docs/9.4/static/sql-copy.html#AEN71994</a>
      <br>
      <br>
    </blockquote>
    <br>
  </body>
</html>