2013-07-26 9 views
5

Czy jest możliwe uzyskanie maksymalnej liczby kolumn obsługiwanych z poziomu sqlite3 w czasie wykonywania? To ograniczenie bazy danych jest ustalane za pomocą zmiennej czasu kompilacji SQLITE_MAX_COLUMN (patrz limits). Wartością domyślną jest zwykle 2000 kolumn.Określanie maksymalnej liczby kolumn z sqlite3

Szukam czegoś dostępnego z poziomu interfejsu Python lub SQL.

Odpowiedz

7

Wydaje się to niemożliwe z praktycznego punktu widzenia (tj. Bez bardzo kosztownej metody "brute-force" na zasadzie odpowiedzi raczej dan04).

źródło (1, 2) modułu sqlite3 nie zawiera odniesienie albo do SQLITE_MAX_COLUMN lub w czasie kompilacji ogranicza ogólnie; nie wydaje się też, aby można było uzyskać do nich dostęp z poziomu interfejsu SQL.

UPDATE:

Prosta modyfikacja dan04's solution użyć przeszukiwanie binarne znacznie przyspiesza rzeczy:

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 

Running powyższy kod poprzez 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] 

.. ., który dochodzi do średniego czasu pracy 30,76/150 = 0,205 sekundy (w przypadku quad-co 2,6 GHz re machine) - nie dokładnie szybka, ale prawdopodobnie bardziej użyteczna niż 15-20 sekund od "kopnięcia", aż złamie "metodę liczenia od jednego".

+0

niesamowite podejście, +1! –

3

Prosty, ale niewydajny sposób to zrobić z poziomu Pythona:

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! To całkiem pomysłowe. +1 za czystą brutalność, nawet jeśli uruchomienie mojej maszyny zajmuje prawie 20 sekund :-) –

+1

@ZeroPiraeus: Istnieją optymalizacje, które możesz wykonać. Na przykład użycie wykładniczego wzrostu w celu znalezienia górnej granicy i bisekcji w celu znalezienia niższej granicy zmniejszyłoby liczbę tabel utworzonych od N do O (log N). Możesz także zacząć od sprawdzenia 2000 i 2001 przy założeniu, że większość kompilacji SQLite użyje tylko domyślnej opcji 'SQLITE_MAX_COLUMN'. – dan04

+0

Wygląda na to, że zdajesz sobie sprawę, że w tym samym czasie zrobiłam to :-) – dan04

Powiązane problemy