Fixed #2272 -- Improved SQLite database introspection. Thanks, dne@mayonnaise.net

git-svn-id: http://code.djangoproject.com/svn/django/trunk@3285 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-07-07 04:06:00 +00:00
parent 84dda1990f
commit 49e5f5450d
3 changed files with 46 additions and 6 deletions

View File

@ -54,6 +54,7 @@ answer newbie questions, and generally made Django that much better:
Jason Davies (Esaj) <http://www.jasondavies.com/> Jason Davies (Esaj) <http://www.jasondavies.com/>
Alex Dedul Alex Dedul
deric@monowerks.com deric@monowerks.com
dne@mayonnaise.net
Jeremy Dunck <http://dunck.us/> Jeremy Dunck <http://dunck.us/>
Clint Ecker Clint Ecker
gandalf@owca.info gandalf@owca.info

View File

@ -2,18 +2,56 @@ from django.db import transaction
from django.db.backends.sqlite3.base import quote_name from django.db.backends.sqlite3.base import quote_name
def get_table_list(cursor): def get_table_list(cursor):
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name") "Returns a list of table names in the current database."
# Skip the sqlite_sequence system table used for autoincrement key
# generation.
cursor.execute("""
SELECT name FROM sqlite_master
WHERE type='table' AND NOT name='sqlite_sequence'
ORDER BY name""")
return [row[0] for row in cursor.fetchall()] return [row[0] for row in cursor.fetchall()]
def get_table_description(cursor, table_name): def get_table_description(cursor, table_name):
cursor.execute("PRAGMA table_info(%s)" % quote_name(table_name)) "Returns a description of the table, with the DB-API cursor.description interface."
return [(row[1], row[2], None, None) for row in cursor.fetchall()] return [(info['name'], info['type'], None, None, None, None,
info['null_ok']) for info in _table_info(cursor, table_name)]
def get_relations(cursor, table_name): def get_relations(cursor, table_name):
raise NotImplementedError raise NotImplementedError
def get_indexes(cursor, table_name): def get_indexes(cursor, table_name):
raise NotImplementedError """
Returns a dictionary of fieldname -> infodict for the given table,
where each infodict is in the format:
{'primary_key': boolean representing whether it's the primary key,
'unique': boolean representing whether it's a unique index}
"""
indexes = {}
for info in _table_info(cursor, table_name):
indexes[info['name']] = {'primary_key': info['pk'] != 0,
'unique': False}
cursor.execute('PRAGMA index_list(%s)' % quote_name(table_name))
# seq, name, unique
for index, unique in [(field[1], field[2]) for field in cursor.fetchall()]:
if not unique:
continue
cursor.execute('PRAGMA index_info(%s)' % quote_name(index))
info = cursor.fetchall()
# Skip indexes across multiple fields
if len(info) != 1:
continue
name = info[0][2] # seqno, cid, name
indexes[name]['unique'] = True
return indexes
def _table_info(cursor, name):
cursor.execute('PRAGMA table_info(%s)' % quote_name(name))
# cid, name, type, notnull, dflt_value, pk
return [{'name': field[1],
'type': field[2],
'null_ok': not field[3],
'pk': field[5] # undocumented
} for field in cursor.fetchall()]
# Maps SQL types to Django Field types. Some of the SQL types have multiple # Maps SQL types to Django Field types. Some of the SQL types have multiple
# entries here because SQLite allows for anything and doesn't normalize the # entries here because SQLite allows for anything and doesn't normalize the

View File

@ -126,8 +126,9 @@ you run it, you'll want to look over the generated models yourself to make
customizations. In particular, you'll need to rearrange models' order, so that customizations. In particular, you'll need to rearrange models' order, so that
models that refer to other models are ordered properly. models that refer to other models are ordered properly.
Primary keys are automatically introspected for PostgreSQL and MySQL, in which Primary keys are automatically introspected for PostgreSQL, MySQL and
case Django puts in the ``primary_key=True`` where needed. SQLite, in which case Django puts in the ``primary_key=True`` where
needed.
``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection ``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection
only works in PostgreSQL and with certain types of MySQL tables. only works in PostgreSQL and with certain types of MySQL tables.