Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

bidang jumlah pyodbc to_sql salah atau kesalahan sintaksis

Pada saat pertanyaan ini diajukan, pandas 0.23.0 baru saja dirilis. Versi itu mengubah perilaku default .to_sql() dari memanggil DBAPI .executemany() metode untuk membuat konstruktor nilai tabel (TVC) yang akan meningkatkan kecepatan unggah dengan menyisipkan beberapa baris dengan satu .execute() panggilan pernyataan INSERT. Sayangnya pendekatan itu sering melebihi batas T-SQL dari 2100 nilai parameter untuk prosedur tersimpan, yang mengarah ke kesalahan yang dikutip dalam pertanyaan.

Tak lama kemudian, rilis panda berikutnya menambahkan method= argumen ke .to_sql() . Default – method=None – memulihkan perilaku sebelumnya menggunakan .executemany() , sambil menentukan method="multi" akan memberi tahu .to_sql() untuk menggunakan pendekatan TVC yang lebih baru.

Sekitar waktu yang sama, SQLAlchemy 1.3 dirilis dan menambahkan fast_executemany=True argumen ke create_engine() yang sangat meningkatkan kecepatan unggah menggunakan driver ODBC Microsoft untuk SQL Server. Dengan peningkatan itu, method=None terbukti setidaknya secepat method="multi" sambil menghindari batas parameter 2.100.

Jadi dengan versi panda, SQLAlchemy, dan pyodbc saat ini, pendekatan terbaik untuk menggunakan .to_sql() dengan driver ODBC Microsoft untuk SQL Server adalah menggunakan fast_executemany=True dan perilaku default .to_sql() , yaitu,

connection_uri = (
    "mssql+pyodbc://scott:tiger^[email protected]/db_name"
    "?driver=ODBC+Driver+17+for+SQL+Server"
)
engine = create_engine(connection_uri, fast_executemany=True)
df.to_sql("table_name", engine, index=False, if_exists="append")

Ini adalah pendekatan yang disarankan untuk aplikasi yang berjalan di Windows, macOS, dan varian Linux yang didukung Microsoft untuk driver ODBC-nya. Jika Anda perlu menggunakan FreeTDS ODBC, maka .to_sql() dapat dipanggil dengan method="multi" dan chunksize= seperti yang dijelaskan di bawah ini.

(Jawaban asli)

Sebelum pandas versi 0.23.0, to_sql akan menghasilkan INSERT terpisah untuk setiap baris di DataTable:

exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2)',
    0,N'row000'
exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2)',
    1,N'row001'
exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2)',
    2,N'row002'

Agaknya untuk meningkatkan kinerja, pandas 0.23.0 sekarang menghasilkan konstruktor nilai tabel untuk menyisipkan beberapa baris per panggilan

exec sp_prepexec @p1 output,N'@P1 int,@P2 nvarchar(6),@P3 int,@P4 nvarchar(6),@P5 int,@P6 nvarchar(6)',
    N'INSERT INTO df_to_sql_test (id, txt) VALUES (@P1, @P2), (@P3, @P4), (@P5, @P6)',
    0,N'row000',1,N'row001',2,N'row002'

Masalahnya adalah bahwa prosedur tersimpan SQL Server (termasuk prosedur tersimpan sistem seperti sp_prepexec ) dibatasi hingga 2100 parameter, jadi jika DataFrame memiliki 100 kolom maka to_sql hanya dapat menyisipkan sekitar 20 baris sekaligus.

Kami dapat menghitung chunksize yang diperlukan menggunakan

# df is an existing DataFrame
#
# limit based on sp_prepexec parameter count
tsql_chunksize = 2097 // len(df.columns)
# cap at 1000 (limit for number of rows inserted by table-value constructor)
tsql_chunksize = 1000 if tsql_chunksize > 1000 else tsql_chunksize
#
df.to_sql('tablename', engine, index=False, if_exists='replace',
          method='multi', chunksize=tsql_chunksize)

Namun, pendekatan tercepat masih mungkin:

  • membuang DataFrame ke file CSV (atau yang serupa), lalu

  • minta Python memanggil SQL Server bcp utilitas untuk mengunggah file itu ke dalam tabel.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengoptimalkan TempDB:Menghindari Kemacetan dan Masalah Kinerja

  2. Prosesor Intel yang Direkomendasikan untuk Beban Kerja SQL Server 2014

  3. Kesalahan Umum DBA di MS SQL Server

  4. EF 6 - Cara melakukan kueri paralel dengan benar

  5. Bagaimana saya bisa terhubung ke SQL Server menggunakan keamanan terintegrasi dengan driver JDBC?