2013-07-26 21 views
5

È possibile ottenere il numero massimo di colonne supportate da sqlite3 in fase di esecuzione? Questa limitazione del database viene stabilita con una variabile in fase di compilazione SQLITE_MAX_COLUMN (vedere limits). L'impostazione predefinita è normalmente 2000 colonne.Determinare il numero massimo di colonne da sqlite3

Sto cercando qualcosa accessibile dall'interfaccia Python o SQL.

risposta

7

Questo sembra essere impossibile in termini pratici (cioè senza un approccio di forza bruta molto costoso sulla falsariga della risposta piuttosto brillante di dan04).

La fonte (1, 2) per il modulo sqlite3 contiene alcun riferimento né SQLITE_MAX_COLUMN o compilare tempo limiti in generale; né sembra esserci alcun modo per accedervi dall'interno dell'interfaccia SQL.

UPDATE:

una semplice modifica di dan04's solution usare una ricerca binaria accelera le cose in modo considerevole:

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 

L'esecuzione del codice di cui sopra attraverso 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] 

.. che raggiunge un tempo di esecuzione medio di 30.76/150 = 0.205 secondi (su un quad-co a 2.6 GHz re machine) - non esattamente veloce, ma probabilmente più utilizzabile dei 15-20 secondi del metodo "calcola fino a quando non si rompe" da un metodo.

+0

approccio Impressionante, +1! –

3

Un modo semplice ma inefficiente per fare questo da Python:

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

Ha! È abbastanza geniale. +1 per pura brutalità, anche se ci vogliono quasi 20 secondi per funzionare sulla mia macchina :-) –

+1

@ZeroPiraeus: Ci sono ottimizzazioni che potresti eseguire. Ad esempio, l'utilizzo della crescita esponenziale per trovare il limite superiore e la bisezione per trovare il limite inferiore ridurrebbe il numero di tabelle create da N a O (log N). Si potrebbe anche iniziare verificando il 2000 e il 2001 partendo dal presupposto che la maggior parte delle build SQLite utilizzerà solo l'opzione predefinita 'SQLITE_MAX_COLUMN'. – dan04

+0

E sembra che tu ti sia reso conto che allo stesso tempo l'ho fatto :-) – dan04

Problemi correlati