2013-07-26 8 views
5

से अधिकतम कॉलम निर्धारित करें क्या रनटाइम पर sqlite3 से समर्थित कॉलम की अधिकतम संख्या प्राप्त करना संभव है? यह डेटाबेस सीमा संकलन-समय परिवर्तनीय SQLITE_MAX_COLUMN (limits देखें) के साथ स्थापित की गई है। डिफ़ॉल्ट रूप से 2000 कॉलम डिफ़ॉल्ट है।sqlite3

मैं पाइथन या एसक्यूएल इंटरफेस से कुछ सुलभ खोज रहा हूं।

उत्तर

7

व्यावहारिक शर्तों में यह असंभव प्रतीत होता है (यानी dan04 के शानदार जवाब के साथ-साथ एक बहुत महंगा ब्रूट-बल दृष्टिकोण के बिना)।

स्रोत (1, 2) sqlite3 मॉड्यूल के लिए या तो SQLITE_MAX_COLUMN करने के लिए या संकलन समय के लिए सामान्य रूप में सीमा में कोई चर्चा नहीं होता है; न तो एसक्यूएल इंटरफेस के भीतर से उन्हें एक्सेस करने का कोई तरीका नहीं दिखता है।

अद्यतन:

एक द्विआधारी खोज का उपयोग करने dan04's solution का एक सरल संशोधन चीजों को गति काफी:

import sqlite3 

def max_columns(): 
    db = sqlite3.connect(':memory:') 
    low = 1 
    high = 32767 # hard limit <http://www.sqlite.org/limits.html> 
    while low < high - 1: 
     guess = (low + high) // 2 
     try: 
      db.execute('CREATE TABLE T%d (%s)' % (
       guess, ','.join('C%d' % i for i in range(guess)) 
      )) 
     except sqlite3.DatabaseError as ex: 
      if 'too many columns' in str(ex): 
       high = guess 
      else: 
       raise 
     else: 
      low = guess 
    return low 

timeit.repeat() के माध्यम से उपरोक्त कोड चल रहा है:

>>> max_columns() 
2000 
>>> import timeit 
>>> timeit.repeat(
...  "max_columns()", 
...  setup="from __main__ import max_columns", 
...  number=50 
...) 
[10.347190856933594, 10.0917809009552, 10.320987939834595] 

.. जो 30.76/150 = 0.205 सेकेंड के औसत रन-टाइम में आता है (2.6 गीगाहर्ट्ज़ क्वाड-सह पर पुनः मशीन) - बिल्कुल तेज नहीं है, लेकिन "इसे लात मारने" के 15-20 सेकेंड से अधिक उपयोग करने योग्य होने की संभावना है "यह एक विधि से गिनती है।

+0

बहुत बढ़िया दृष्टिकोण, +1! –

3

अजगर से यह करने के लिए एक सरल लेकिन अक्षम रास्ता:

import itertools 
import sqlite3 

db = sqlite3.connect(':memory:') 
try: 
    for num_columns in itertools.count(1): 
     db.execute('CREATE TABLE T%d (%s)' % (num_columns, ','.join('C%d' % i for i in range(num_columns)))) 
except sqlite3.DatabaseError as ex: 
    if 'too many columns' in str(ex): 
     print('Max columns = %d' % (num_columns - 1)) 
+1

हा! यह काफी सरल है। शीयर क्रूरता के लिए +1, भले ही इसे मेरी मशीन पर चलाने में लगभग 20 सेकंड लगते हैं :-) –

+1

@ ज़ीरोपीरायस: ऑप्टिमाइज़ेशन आप कर सकते हैं। उदाहरण के लिए, निचले बाउंड को खोजने के लिए ऊपरी बाउंड और बायसेक्शन को खोजने के लिए घातीय वृद्धि का उपयोग करना एन से ओ (लॉग एन) से बनाए गए तालिकाओं की संख्या को कम करेगा। आप इस धारणा पर 2000 और 2001 की जांच करके भी शुरू कर सकते हैं कि अधिकांश SQLite बिल्ड केवल डिफ़ॉल्ट 'SQLITE_MAX_COLUMN' विकल्प का उपयोग करेंगे। – dan04

+0

और ऐसा लगता है कि आपको एहसास हुआ कि एक ही समय में मैंने किया :-) – dan04