2013-07-26 20 views
5

Có thể nhận số cột tối đa được hỗ trợ từ sqlite3 khi chạy không? Giới hạn cơ sở dữ liệu này được thiết lập với biến biên dịch SQLITE_MAX_COLUMN (xem limits). Mặc định thường là 2000 cột.Xác định số cột tối đa từ sqlite3

Tôi đang tìm kiếm thứ gì đó có thể truy cập được từ giao diện Python hoặc SQL.

Trả lời

7

Điều này dường như là không thể trong điều khoản thực tế (nghĩa là không có phương pháp tiếp cận vũ phu mạnh mẽ dọc theo dòng câu trả lời khá rực rỡ của dan04).

Nguồn (1, 2) cho các mô-đun sqlite3 không chứa tài liệu tham khảo hoặc để SQLITE_MAX_COLUMN hoặc để biên dịch-thời hạn nói chung; dường như không có cách nào để truy cập chúng từ bên trong giao diện SQL.

UPDATE:

Một sửa đổi đơn giản của dan04's solution sử dụng tìm kiếm nhị phân tốc độ điều lên đáng kể:

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 

Chạy mã trên qua 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] 

.. . Thời gian chạy trung bình là 30,76/150 = 0,205 giây (trên quad-quad 2,6 GHz máy tái) - không chính xác nhanh, nhưng có khả năng sử dụng được nhiều hơn 15-20 giây của "đá" cho đến khi nó phá vỡ "phương pháp đếm-từ-một.

+0

cách tiếp cận Awesome, 1! –

3

Một cách đơn giản nhưng hiệu quả để làm điều này từ 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! Đó là khá khéo léo. 1 cho sự tàn bạo tuyệt đối, ngay cả khi nó mất gần 20 giây để chạy trên máy của tôi :-) –

+1

@ZeroPiraeus: Có tối ưu hóa bạn có thể thực hiện. Ví dụ, sử dụng tăng trưởng theo hàm mũ để tìm giới hạn trên và bisection để tìm giới hạn dưới sẽ giảm số lượng các bảng được tạo từ N thành O (log N). Bạn cũng có thể bắt đầu bằng cách kiểm tra năm 2000 và 2001 trên giả định rằng hầu hết các bản dựng SQLite sẽ chỉ sử dụng tùy chọn 'SQLITE_MAX_COLUMN' mặc định. – dan04

+0

Và có vẻ như bạn nhận ra rằng cùng một lúc tôi đã làm :-) – dan04