information_schema.columns
should provide you with the column data-type info.
For example, given this DDL:
create table foo
(
id serial,
name text,
val int
);
insert into foo (name, val) values ('narf', 1), ('poit', 2);
And this query (filtering out the meta tables to get at your tables):
select *
from information_schema.columns
where table_schema NOT IN ('information_schema', 'pg_catalog')
order by table_schema, table_name;
Will yield 4 rows, for the table foo
-- the three columns I defined, plus a FK.
SQL fiddle
Regarding psycopg2, the information_schema
-related code that you have shown looks like it should work... What's the entirety of the code? I would also recommend trying to step through the code in a debugger (the built-in pdb is OK, but I would recommend pudb, as it's more full featured and easier to use, but still terminal-based. It only runs on *nix platforms, though, due to the underlying modules it uses.
Edit:
I was able to get the data_type
info from information_schema
using psycopg2 with the following code:
#!/usr/bin/env python
import psycopg2
import psycopg2.extras
conn = psycopg2.connect("host=<host> dbname=<dbname> user=<user> password=<password>")
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cur.execute("""select *
from information_schema.columns
where table_schema NOT IN ('information_schema', 'pg_catalog')
order by table_schema, table_name""")
for row in cur:
print "schema: {schema}, table: {table}, column: {col}, type: {type}".format(
schema = row['table_schema'], table = row['table_name'],
col = row['column_name'], type = row['data_type'])
I prefer to use DictCursor
s, as I find them much easier to work with, but it should work with a regular cursor, too -- you would just need to change how you accessed the rows.
Also, regarding cur.description
, that returns a tuple of tuples. If you want to get at the type_code there, you can do so like this:
print cur.description[0][1]
Where the first dimension in the index of the column you want to look at, and the second dimension is the datum within that column. type_code
is always 1. So you could iterate over the outer tuple and always look at its second item, for example.