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 <[email protected]> wrote:
> On Sun, Aug 29, 2021 at 7:51 PM Rob Galanakis <[email protected]> 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
> [email protected].
> 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 [email protected].
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.