Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

to_sql pyodbc गिनती फ़ील्ड गलत या सिंटैक्स त्रुटि

जिस समय यह प्रश्न पूछा गया था, उस समय पांडा 0.23.0 जारी किया गया था। उस संस्करण ने .to_sql() . के डिफ़ॉल्ट व्यवहार को बदल दिया DBAPI को कॉल करने से .executemany() एक टेबल-वैल्यू कंस्ट्रक्टर (TVC) बनाने की विधि जो एक .execute() के साथ कई पंक्तियों को सम्मिलित करके अपलोड गति में सुधार करेगी। INSERT स्टेटमेंट की कॉल। दुर्भाग्य से वह दृष्टिकोण अक्सर संग्रहीत कार्यविधि के लिए टी-एसक्यूएल की 2100 पैरामीटर मानों की सीमा से अधिक हो जाता है, जिससे प्रश्न में उद्धृत त्रुटि हो जाती है।

इसके तुरंत बाद, पंडों की एक बाद की रिलीज़ ने एक method= जोड़ा .to_sql() . के लिए तर्क . डिफ़ॉल्ट - method=None - .executemany() . का उपयोग करने के पिछले व्यवहार को पुनर्स्थापित किया , method="multi" . निर्दिष्ट करते समय बता देंगे .to_sql() नए टीवीसी दृष्टिकोण का उपयोग करने के लिए।

लगभग उसी समय, SQLAlchemy 1.3 जारी किया गया था और इसमें एक fast_executemany=True जोड़ा गया था। create_engine() . के लिए तर्क जिसने SQL सर्वर के लिए Microsoft के ODBC ड्राइवरों का उपयोग करके अपलोड गति में बहुत सुधार किया। उस एन्हांसमेंट के साथ, method=None कम से कम method="multi" . जितना तेज़ साबित हुआ 2100-पैरामीटर की सीमा से बचते हुए।

तो पांडा, SQLAlchemy, और pyodbc के मौजूदा संस्करणों के साथ, .to_sql() का उपयोग करने के लिए सबसे अच्छा तरीका है SQL सर्वर के लिए Microsoft के ODBC ड्राइवरों के साथ fast_executemany=True का उपयोग करना है और .to_sql() . का डिफ़ॉल्ट व्यवहार , यानी,

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")

विंडोज़, मैकोज़ और लिनक्स वेरिएंट पर चलने वाले ऐप्स के लिए यह अनुशंसित दृष्टिकोण है कि माइक्रोसॉफ्ट अपने ओडीबीसी ड्राइवर के लिए समर्थन करता है। यदि आपको FreeTDS ODBC का उपयोग करने की आवश्यकता है, तो .to_sql() method="multi" . के साथ कॉल किया जा सकता है और chunksize= जैसा कि नीचे वर्णित है।

(मूल उत्तर)

पांडा संस्करण 0.23.0 से पहले, to_sql डेटाटेबल में प्रत्येक पंक्ति के लिए एक अलग INSERT उत्पन्न करेगा:

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'

संभवतः प्रदर्शन में सुधार करने के लिए, पांडा 0.23.0 अब प्रति कॉल कई पंक्तियों को सम्मिलित करने के लिए एक टेबल-वैल्यू कंस्ट्रक्टर उत्पन्न करता है

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'

समस्या यह है कि SQL सर्वर संग्रहीत कार्यविधियाँ (सिस्टम संग्रहीत कार्यविधियाँ जैसे sp_prepexec . सहित) ) 2100 पैरामीटर तक सीमित हैं, इसलिए यदि डेटाफ़्रेम में 100 कॉलम हैं तो to_sql एक बार में केवल 20 पंक्तियाँ ही सम्मिलित कर सकता है।

हम आवश्यक chunksize . की गणना कर सकते हैं

. का उपयोग करना
# 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)

हालांकि, सबसे तेज़ तरीका अभी भी होने की संभावना है:

  • DataFrame को CSV फ़ाइल (या समान) में डंप करें, और फिर

  • क्या पायथन को SQL सर्वर bcp पर कॉल करना है? उस फ़ाइल को तालिका में अपलोड करने की उपयोगिता।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. छवियों को एक varbinary (अधिकतम) कॉलम में कैसे स्टोर करें?

  2. कैसे बाधा के साथ कॉलम ड्रॉप करने के लिए?

  3. SQL सर्वर पूर्ण-पाठ खोज के साथ उत्पाद विश्लेषण करना सीखें। भाग 2

  4. SQL सर्वर में, मैं हर जगह एक कॉलम का संदर्भ कैसे पा सकता हूं?

  5. Microsoft SQL सर्वर में विशिष्ट क्रमिक स्थिति में एक नया तालिका स्तंभ जोड़ें