97

I want to get a list of column names from a table in a database. Using pragma I get a list of tuples with a lot of unneeded information. Is there a way to get only the column names? So I might end up with something like this:

[Column1, Column2, Column3, Column4]

The reason why I absolutely need this list is because I want to search for a column name in the list and get the index because the index is used in a lot of my code.

Is there a way of getting a list like this?

Thanks

Denman
  • 1,233
  • 2
  • 11
  • 9

14 Answers14

210

You can use sqlite3 and pep-249

import sqlite3
connection = sqlite3.connect('~/foo.sqlite')
cursor = connection.execute('select * from bar')

cursor.description is description of columns

names = list(map(lambda x: x[0], cursor.description))

Alternatively you could use a list comprehension:

names = [description[0] for description in cursor.description]
isedwards
  • 2,429
  • 21
  • 29
smallredstone
  • 2,216
  • 1
  • 13
  • 2
43

An alternative to the cursor.description solution from smallredstone could be to use row.keys():

import sqlite3

connection = sqlite3.connect('~/foo.sqlite')
connection.row_factory = sqlite3.Row
cursor = connection.execute('select * from bar')
# instead of cursor.description:
row = cursor.fetchone()
names = row.keys()

The drawback: it only works if there is at least a row returned from the query.

The benefit: you can access the columns by their name (row['your_column_name'])

Read more about the Row objects in the python documentation.

xjcl
  • 12,848
  • 6
  • 67
  • 89
flokk
  • 714
  • 8
  • 15
  • 2
    I like the `row_factory` idea much better than the `cursor.description`. Leaving the drawback aside, your code won't be littered with `row[names['column_name']]` and instead, use a more readable pattern of `row['column_name']` (which is the whole point of python after all!). – Prahlad Yeri Dec 23 '16 at 14:09
  • In the rare case that you need the column names regardless of the number of rows returned, you can always use `cursor.description` for *that particular case*. – Prahlad Yeri Dec 23 '16 at 14:09
  • Isn't `row_factory` slow? – benjaminz Apr 21 '17 at 14:33
  • 1
    As a note: One can set the `row_factory` on the cursor as well. (This will then not affect `connection`) To reset it seems like `None` is the way to go. Can not find any `default_row_factory` or the like :D – user3342816 Oct 09 '19 at 19:54
18

As far as I can tell Sqlite doesn't support INFORMATION_SCHEMA. Instead it has sqlite_master.

I don't think you can get the list you want in just one command. You can get the information you need using sql or pragma, then use regex to split it into the format you need

SELECT sql FROM sqlite_master WHERE name='tablename';

gives you something like

CREATE TABLE tablename(
        col1 INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
        col2 NVARCHAR(100) NOT NULL,
        col3 NVARCHAR(100) NOT NULL,
)

Or using pragma

PRAGMA table_info(tablename);

gives you something like

0|col1|INTEGER|1||1
1|col2|NVARCHAR(100)|1||0
2|col3|NVARCHAR(100)|1||0
wdavo
  • 5,070
  • 1
  • 19
  • 20
11

Quick, interactive way to see column names

If you're working interactively in Python and just want to quickly 'see' the column names, I found cursor.description to work.

import sqlite3
conn = sqlite3.connect('test-db.db')
cursor = conn.execute('select * from mytable')
cursor.description

Outputs something like this:

(('Date', None, None, None, None, None, None),
 ('Object-Name', None, None, None, None, None, None),
 ('Object-Count', None, None, None, None, None, None))

Or, quick way to access and print them out.

colnames = cursor.description
for row in colnames:
    print row[0]

Outputs something like this:

Date
Object-Name
Object-Count
Joseph True
  • 621
  • 8
  • 6
  • 3
    What exactly do the multiple 'None's refer to in the output of `cursor.descrition`? – Mitchell van Zuylen May 31 '17 at 10:11
  • 3
    Looks like the 'None's are just empty placeholders "... To remain compatible with the Python DB API ..." according to Python docs. See: https://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.description – Joseph True May 31 '17 at 15:34
  • 1
    @Mitchell van Zuylen is a 7-plet which describes the `cursor.descriptor`-property: `name, type_code, display_size, internal_size, precision, scale, null_ok` – cards May 19 '22 at 21:38
11

You can get a list of column names by running:

SELECT name FROM PRAGMA_TABLE_INFO('your_table');
name      
tbl_name  
rootpage  
sql

You can check if a certain column exists by running:

SELECT 1 FROM PRAGMA_TABLE_INFO('your_table') WHERE name='sql';
1

Reference:

https://www.sqlite.org/pragma.html#pragfunc

user1461607
  • 2,416
  • 1
  • 25
  • 23
8

Assuming that you know the table name, and want the names of the data columns you can use the listed code will do it in a simple and elegant way to my taste:

import sqlite3

def get_col_names():
#this works beautifully given that you know the table name
    conn = sqlite3.connect("t.db")
    c = conn.cursor()
    c.execute("select * from tablename")
    return [member[0] for member in c.description]
thebeancounter
  • 4,261
  • 8
  • 61
  • 109
  • thanks, this is better than the fetch in another answer because getting the column header doesn't start iterating through the rows, which would cause you to have to rewind if you don't want to skip row 1 in further processing – Davos Feb 09 '17 at 06:00
8

It is very easy.
First create a connection , lets name it, con. Then run the following code.

cur =con.cursor()
cur.execute("select * from table_name limit 1")
col_name=[i[0] for i in cur.description]
print(col_name)

You will get column name as a list

Atif
  • 1,012
  • 1
  • 9
  • 23
3

Well, I may be very late to answer this but since people still follow this thread, I just wanted to share how I use to get the list of column names in python sqlite3.

import sqlite3

def getVarList(con, tableName)
    return [fields[1] for fields in con.execute(f"PRAGMA table_info({tableName})").fetchall()]
    
conn = sqlite3.connect('foo.db')
varList = getVarList(conn, 'bar')
ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
2

I use this:

import sqlite3

    db = sqlite3.connect('~/foo.sqlite')
    dbc = db.cursor()
    dbc.execute("PRAGMA table_info('bar')"
    ciao = dbc.fetchall()

    HeaderList=[]
    for i in ciao:
        counter=0
        for a in i:
            counter+=1
            if( counter==2):
                HeaderList.append(a)

print(HeaderList)
1

I like the answer by @thebeancounter, but prefer to parameterize the unknowns, the only problem being a vulnerability to exploits on the table name. If you're sure it's okay, then this works:

def get_col_names(cursor, tablename):
    """Get column names of a table, given its name and a cursor
       (or connection) to the database.
    """
    reader=cursor.execute("SELECT * FROM {}".format(tablename))
    return [x[0] for x in reader.description] 

If it's a problem, you could add code to sanitize the tablename.

4dummies
  • 759
  • 2
  • 9
  • 22
  • 1
    I don't think this is secure. Probably you should use the sqlite3-specific `?` wildcard inside queries instead of the generic python `"stuff{}".format(string)` approach. From the [sqlite3 documentation](https://docs.python.org/3/library/sqlite3.html): ```t = ('RHAT',); c.execute('SELECT * FROM stocks WHERE symbol=?', t)``` – Curt F. Oct 10 '20 at 12:46
1

Since the question has a python flag. I feel free to post a python specific answer with pandas:

import sqlite3
import pandas as pd

path_to_db = 'path/to/db'
connect = sqlite3.connect(path_to_db, isolation_level=None)
table = 'table_name'

column_list = list(pd.read_sql_query(f"SELECT * FROM {table} limit 1", connect).columns)
Thomas R
  • 1,067
  • 11
  • 17
1
import sqlite3

with sqlite3.connect('statics.db') as cur:
    cur.execute("CREATE TABLE IF NOT EXISTS data(id INT PRIMARY KEY NOT NULL)")
    pragmas = cur.execute("PRAGMA table_info(data);")
    columns = [n for _, n, *_ in pragmas.fetchall()]
    print(columns)
itchenfei
  • 19
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 07 '22 at 14:38
0

Another way of using pragma:

> table = "foo"
> cur.execute("SELECT group_concat(name, ', ') FROM pragma_table_info(?)", (table,))
> cur.fetchone()
('foo', 'bar', ...,)
user3342816
  • 974
  • 10
  • 24
0

If you are fine with using pandas, I recommend using pandas.read_sql_query, which will give you back a full DataFrame including the column names as header; this also nicely formats to stdout.

import pandas as pd
import sqlite3

with sqlite3.connect("my_db_file.db") as conn:
    df = pd.read_sql_query("SELECT * FROM foo", conn)
    print(df)  # use df.columns.tolist() for only the header
xjcl
  • 12,848
  • 6
  • 67
  • 89