activerecord-sqlserver-adapter icon indicating copy to clipboard operation
activerecord-sqlserver-adapter copied to clipboard

ActiveRecord::ConnectionAdapters::SQLServerAdapter does not support skipping duplicates

Open Quintasan opened this issue 3 years ago • 5 comments

Issue

bundle exec rails db:seed throws ActiveRecord::ConnectionAdapters::SQLServerAdapter does not support skipping duplicates.

Expected behavior

A single SQL INSERT should be generated and executed

Actual behavior

When using #insert_all(Array[Hash]) I'm getting ActiveRecord::ConnectionAdapters::SQLServerAdapter does not support skipping duplicates

How to reproduce


ENTRIES = [{name: "Test"}]
ENTRIES_DATA = ENTRIES.map { |e| e.merge(created_at: Time.zone.now, updated_at: Time.zone.now) }
Model.insert_all(ENTRIES_DATA)

Details

  • Rails version: Rails 6.0.3.4
  • SQL Server adapter version: 6.0.0
  • TinyTDS version: 2.1.3
  • FreeTDS details: 1.1.6-1ubuntu0.1
Compile-time settings (established with the "configure" script)
                            Version: freetds v1.1.6
             freetds.conf directory: /etc/freetds
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: auto
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: yes
                            OpenSSL: no
                             GnuTLS: yes
                               MARS: yes

Quintasan avatar Oct 19 '20 10:10 Quintasan

@Quintasan did you find a solution or workaround for this? I'm seeing the same behavior with PostgreSQLAdapter. I worry it's an environment thing, because it works fine on my colleagues computer.

jeffchuber avatar Jan 20 '21 16:01 jeffchuber

The only workaround I could think of was using find_or_create_by.

Quintasan avatar Jan 20 '21 16:01 Quintasan

I got "something" working... for some reason insert_all! works while insert_all does not. 🤷 🤦

jeffchuber avatar Jan 20 '21 16:01 jeffchuber

Some info I gathered while working on the issue https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/859.

insert_all semantic is "skip on duplicates". ActiveRercord validates that the database adapter supports "skip on duplicate" when you call Model.insert_all, before reaching the adapters code and even with a single record. Mysql adapter supports it. Postgresql adapter supports it starting on version 90500 (I guess 90500 means version 9.5). This adapter doesn't.

insert_all! semantic is "raise on duplicate" (raise ActiveRecord::RecordNotUnique on duplicates).

Since the issue involves just one record, as mentioned, using insert_all! and rescuing from ActiveRecord::RecordNotUnique or calling find_or_create_by are valid workarounds.

mgrunberg avatar Apr 07 '21 17:04 mgrunberg

Thanks @mgrunberg . I ended up finding out that psql --versionwas lying to me and I had an older version than it was letting on. Now insert_all, upsert_all, etc - all work fine.

jeffchuber avatar Apr 07 '21 18:04 jeffchuber