For now I went with something like this (my actual implementation isn't
quite so general):

```
module Bulk
  class Ref
    attr_accessor :instance
    def initialize(instance)
      @instance = instance
    end
  end
  class Creator
    def initialize(model_cls)
      @model_cls = model_cls
      @refs = []
    end
    def prepare(instance)
      r = Ref.new(instance)
      @refs << r
      return r
    end
    def create_all
      pks = @model_cls.multi_insert(@refs.map(&:instance), return:
:primary_key)
      by_pk = @model_cls.where(id: pks).all.index_by(&:pk)
      refs = @refs
      @refs = []
      refs.each_with_index do |ref, i|
        inserted_pk = pks[i]
        ref.instance = by_pk[inserted_pk]
      end
      return refs
    end
  end
end
```

I don't mind the additional caller complexity of having to use
`ref.instance` for now; I'm a bit hesitant to go the plugin route since it
will have to muck around with the guts of Model. But I'll keep it in mind
if I need it in the future (for what it's worth, I have had to add a
Sequel-style multi_insert helper for every significant Django project I
work on; this is the first time I've needed a Django-style bulk_create
helper in 7 years of Sequel).

- Rob

On Sun, Aug 29, 2021 at 8:01 PM Jeremy Evans <jeremyeva...@gmail.com> wrote:

> On Sun, Aug 29, 2021 at 7:51 PM Rob Galanakis <r...@lithic.tech> wrote:
>
>> I am trying to optimize some code to use bulk creation of models- on the
>> order of dozens, not hundreds, and I do still need models, so raw dataset
>> methods aren't suitable.
>>
>> I don't see a way to do this with Sequel- we have Dataset#import and
>> #multi_insert, and they can return an array of primary keys. But there is
>> internal machinery in Model (@new and @modified attributes among others)
>> that is unavailable, so even if I set the primary key value, the model
>> still thinks it is new. It'd be nice at times to "enqueue" an unsaved model
>> for bulk insert; save it; and then use it once saved.
>>
>> Is this something reasonable to add? Django, which for the most part I
>> loathe, has this sort of thing (of course its bulk create is entirely
>> hand-rolled and does not use underlying database machinery so is filled
>> with other issues). It would also seem possible to work around this by
>> being able to update a model in-place, or something like 'refreshing' it
>> from some data rather than the database (`_clear_changed_columns` is not
>> enough because of the internal attributes).
>>
>
> I don't think it sounds like something I'd want to add to Sequel::Model,
> but I'd have to see an implementation.  There would have to be some
> significant advantage over the equivalent of:
>
>   enumerable.each{ModelClass.create(...)}
>
> It would also have to be general enough that I could see a substantial
> number of people using it.
>
> You might want to start out creating a plugin for what you want.
>
> Thanks,
> Jeremy
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "sequel-talk" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/sequel-talk/w8pWnUWHaC4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> sequel-talk+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sequel-talk/CADGZSSfZpD2JnMowS9oh_H_tffDdfDGBw%3Dhec0WKRpz2_QoD0A%40mail.gmail.com
> <https://groups.google.com/d/msgid/sequel-talk/CADGZSSfZpD2JnMowS9oh_H_tffDdfDGBw%3Dhec0WKRpz2_QoD0A%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sequel-talk+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sequel-talk/CAMXo6Re%2Bs5uDaCREwU1_%3DkBOp-uDtRPU_K1un0VSvJ%2B9KsPv4A%40mail.gmail.com.

Reply via email to