1 | *** introspection.py.orig 2008-06-06 11:27:04.000000000 -0500
|
---|
2 | --- introspection.py 2008-06-06 15:51:17.000000000 -0500
|
---|
3 | ***************
|
---|
4 | *** 1,28 ****
|
---|
5 | import re
|
---|
6 |
|
---|
7 | foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
|
---|
8 |
|
---|
9 | def get_table_list(cursor):
|
---|
10 | "Returns a list of table names in the current database."
|
---|
11 | cursor.execute("SELECT TABLE_NAME FROM USER_TABLES")
|
---|
12 | return [row[0] for row in cursor.fetchall()]
|
---|
13 |
|
---|
14 | def get_table_description(cursor, table_name):
|
---|
15 | ! return table_name
|
---|
16 |
|
---|
17 | def _name_to_index(cursor, table_name):
|
---|
18 | """
|
---|
19 | Returns a dictionary of {field_name: field_index} for the given table.
|
---|
20 | Indexes are 0-based.
|
---|
21 | """
|
---|
22 | ! return dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name))])
|
---|
23 |
|
---|
24 | def get_relations(cursor, table_name):
|
---|
25 | """
|
---|
26 | Returns a dictionary of {field_index: (field_index_other_table, other_table)}
|
---|
27 | representing all relationships to the given table. Indexes are 0-based.
|
---|
28 | """
|
---|
29 | ! raise NotImplementedError
|
---|
30 |
|
---|
31 | def get_indexes(cursor, table_name):
|
---|
32 | """
|
---|
33 | --- 1,81 ----
|
---|
34 | +
|
---|
35 | import re
|
---|
36 |
|
---|
37 | foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
|
---|
38 |
|
---|
39 | + from cx_Oracle import NUMBER, ROWID, LONG_STRING, STRING, FIXED_CHAR, Timestamp, LOB, BLOB, CLOB, BINARY
|
---|
40 | +
|
---|
41 | +
|
---|
42 | def get_table_list(cursor):
|
---|
43 | "Returns a list of table names in the current database."
|
---|
44 | cursor.execute("SELECT TABLE_NAME FROM USER_TABLES")
|
---|
45 | return [row[0] for row in cursor.fetchall()]
|
---|
46 |
|
---|
47 | + table_description_cache = {}
|
---|
48 | +
|
---|
49 | def get_table_description(cursor, table_name):
|
---|
50 | ! "Returns a description of the table, with the DB-API cursor.description interface."
|
---|
51 | ! cursor.execute("SELECT * FROM \"%s\" where rownum < 2" % table_name)
|
---|
52 | ! return cursor.description
|
---|
53 | !
|
---|
54 | ! _name_to_index_cache = {}
|
---|
55 |
|
---|
56 | def _name_to_index(cursor, table_name):
|
---|
57 | """
|
---|
58 | Returns a dictionary of {field_name: field_index} for the given table.
|
---|
59 | Indexes are 0-based.
|
---|
60 | """
|
---|
61 | ! if not _name_to_index_cache.get(table_name):
|
---|
62 | ! _name_to_index_cache[table_name] = dict([(d[0], i) for i, d in enumerate(get_table_description(cursor, table_name))])
|
---|
63 | ! return _name_to_index_cache[table_name]
|
---|
64 | !
|
---|
65 | !
|
---|
66 | ! def columnum(cursor, table_name, column_name):
|
---|
67 | ! res = _name_to_index(cursor,table_name)[column_name]
|
---|
68 | ! return res
|
---|
69 |
|
---|
70 | def get_relations(cursor, table_name):
|
---|
71 | """
|
---|
72 | Returns a dictionary of {field_index: (field_index_other_table, other_table)}
|
---|
73 | representing all relationships to the given table. Indexes are 0-based.
|
---|
74 | +
|
---|
75 | """
|
---|
76 | !
|
---|
77 | ! cursor.execute("select col.column_name, con.constraint_type from all_cons_columns col, all_constraints con where col.constraint_name = con.constraint_name and con.constraint_type = 'P' and col.table_name = '%s'" % table_name )
|
---|
78 | ! rows = cursor.fetchall()
|
---|
79 | ! try:
|
---|
80 | ! primary_key = rows[0][0];
|
---|
81 | ! except:
|
---|
82 | ! primary_key = None
|
---|
83 | !
|
---|
84 | ! print "Got primary key: ", primary_key
|
---|
85 | !
|
---|
86 | ! res = {}
|
---|
87 | ! query = """
|
---|
88 | ! select col.column_name, col.table_name, col.constraint_name,
|
---|
89 | ! c2.table_name, c2.column_name
|
---|
90 | ! from all_cons_columns col, all_constraints con, all_cons_columns c2
|
---|
91 | ! where con.constraint_type = 'R'
|
---|
92 | ! and con.r_constraint_name = c2.constraint_name
|
---|
93 | ! and con.constraint_name = col.constraint_name
|
---|
94 | ! and not (col.position = c2.position and
|
---|
95 | ! col.table_name = c2.table_name)
|
---|
96 | ! and col.table_name = '%s'
|
---|
97 | ! """
|
---|
98 | ! cursor.execute(query % table_name)
|
---|
99 | ! relations = {}
|
---|
100 | ! rows = cursor.fetchall()
|
---|
101 | ! for row in rows:
|
---|
102 | ! print "relation: %s -> %s(%s)" % (row[0], row[3], row[4])
|
---|
103 | ! if row[0] != primary_key:
|
---|
104 | ! try:
|
---|
105 | ! relations[columnum(cursor, table_name, row[0])] = (
|
---|
106 | ! columnum(cursor,row[3],row[4]),
|
---|
107 | ! row[3]
|
---|
108 | ! )
|
---|
109 | ! except:
|
---|
110 | ! pass
|
---|
111 | ! return relations
|
---|
112 |
|
---|
113 | def get_indexes(cursor, table_name):
|
---|
114 | """
|
---|
115 | ***************
|
---|
116 | *** 31,50 ****
|
---|
117 | {'primary_key': boolean representing whether it's the primary key,
|
---|
118 | 'unique': boolean representing whether it's a unique index}
|
---|
119 | """
|
---|
120 | ! raise NotImplementedError
|
---|
121 |
|
---|
122 | # Maps type codes to Django Field types.
|
---|
123 | DATA_TYPES_REVERSE = {
|
---|
124 | ! 16: 'BooleanField',
|
---|
125 | ! 21: 'SmallIntegerField',
|
---|
126 | ! 23: 'IntegerField',
|
---|
127 | ! 25: 'TextField',
|
---|
128 | ! 869: 'IPAddressField',
|
---|
129 | ! 1043: 'CharField',
|
---|
130 | ! 1082: 'DateField',
|
---|
131 | ! 1083: 'TimeField',
|
---|
132 | ! 1114: 'DateTimeField',
|
---|
133 | ! 1184: 'DateTimeField',
|
---|
134 | ! 1266: 'TimeField',
|
---|
135 | ! 1700: 'FloatField',
|
---|
136 | }
|
---|
137 | --- 84,113 ----
|
---|
138 | {'primary_key': boolean representing whether it's the primary key,
|
---|
139 | 'unique': boolean representing whether it's a unique index}
|
---|
140 | """
|
---|
141 | ! cursor.execute("select col.column_name, con.constraint_type from all_cons_columns col, all_constraints con where col.constraint_name = con.constraint_name and con.constraint_type in ('P','U') and col.table_name = '%s'" % table_name )
|
---|
142 | ! rows = cursor.fetchall()
|
---|
143 | ! res = {}
|
---|
144 | ! for r in rows:
|
---|
145 | ! res[r[0]] = {'primary_key': 0, 'unique': 0}
|
---|
146 | !
|
---|
147 | ! for r in rows:
|
---|
148 | ! if r[1] == 'P':
|
---|
149 | ! res[r[0]]['primary_key'] = 1
|
---|
150 | ! if r[1] == 'U':
|
---|
151 | ! res[r[0]]['unique'] = 1
|
---|
152 | !
|
---|
153 | ! return res
|
---|
154 |
|
---|
155 | # Maps type codes to Django Field types.
|
---|
156 | DATA_TYPES_REVERSE = {
|
---|
157 | ! NUMBER: 'IntegerField',
|
---|
158 | ! ROWID: 'IntegerField',
|
---|
159 | ! LONG_STRING: 'TextField',
|
---|
160 | ! STRING: 'TextField',
|
---|
161 | ! FIXED_CHAR: 'CharField',
|
---|
162 | ! Timestamp: 'DateTimeField',
|
---|
163 | ! LOB: 'TextField',
|
---|
164 | ! BLOB: 'TextField',
|
---|
165 | ! CLOB: 'TextField',
|
---|
166 | ! BINARY:'TextField',
|
---|
167 | }
|
---|