我想对Oracle数据库运行inspectdb。我使用的用户帐户是拥有0个表的只读用户。但是,它可以访问包含所有表的模式。使用inspectdb
时如何指定架构?
我目前的命令是:python manage.py inspectdb --database "oradb" > test_model.py
这仅输出from django.db import models
的文件。
答案 0 :(得分:4)
César对Oracle支持的回答是正确的。但是,我能够通过在两个地方修改django\db\backends\oracle\introspection.py
来生成粗略模型。
将cursor.execute
中的get_table_list
行更改为:
cursor.execute("SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'OTHERSCHEMA'")
将user_table_cols
中第ALL_TAB_COLUMNS
行中的cursor.execute
更改为get_table_description
,内容为:
cursor.execute("""
SELECT
column_name,
data_default,
CASE
WHEN char_used IS NULL THEN data_length
ELSE char_length
END as internal_size
FROM ALL_TAB_COLUMNS
WHERE table_name = UPPER(%s)""", [table_name])
接下来,将cursor.execute
中的第二个get_table_description
行更改为:cursor.execute("SELECT * FROM OTHERSCHEMA.%s WHERE ROWNUM < 2" % self.connection.ops.quote_name(table_name))
由于这是一个遗留数据库,其中策略阻止了对数据库的更改,因此这对于一次运行非常有用。
模型完成后,还需要进行一些更改。看来我的一些类缺少主键引用和外键引用。我会手动添加这些。
我做的最后一次更改是修改所有class Meta:
个实例以引用正确的架构:
class Meta:
db_table = u'"SCHEMA"."TABLE_NAME"' # Notice the quoting needed
答案 1 :(得分:1)
问题是Django的inspectdb不支持Oracle。来自文档:
inspectdb适用于PostgreSQL,MySQL和SQLite。外键 检测仅适用于PostgreSQL和某些类型的MySQL 表。
--database选项可用于指定数据库 内省。
答案 2 :(得分:1)
如果有人遇到这个帖子:Andy的建议+我也改变了get_relations方法以在生成的源中获取外键,在1.9.1中工作:
def get_relations(self, cursor, table_name):
"""
Returns a dictionary of {field_name: (field_name_other_table, other_table)}
representing all relationships to the given table.
"""
table_name = table_name.upper()
cursor.execute("""
SELECT a.column_name, c_pk.table_name r_table_name, c_pk.constraint_name r_pk
FROM all_cons_columns a
JOIN all_constraints c ON a.owner = c.owner
AND a.constraint_name = c.constraint_name
JOIN all_constraints c_pk ON c.r_owner = c_pk.owner
AND c.r_constraint_name = c_pk.constraint_name
WHERE c.constraint_type = 'R'
AND a.table_name = %s""", [table_name])
relations = {}
for row in cursor.fetchall():
relations[row[0].lower()] = (row[2].lower(), row[1].lower())
return relations
答案 3 :(得分:0)
我的两分钱。(django版本1.9.7 + django GIS扩展)
按照Andy和Mirek Simek的建议我进一步修改了:
在 settings.py
中的数据库配置中添加了'schemas' ...
'oracle1': {
'ENGINE': 'django.contrib.gis.db.backends.oracle',
'NAME': 'dbname',
'USER': 'dbuser',
'PASSWORD': 'dbpass',
'HOST': 'dbhostname',
'PORT': 'dbport',
'schemas': ['SCHEMANAME1', ....] #<-- this
},
...
以这种方式修改 get_tables_list :
def get_table_list(self, cursor):
"""
Returns a list of table and view names in the current database.
"""
cursor.execute("SELECT TABLE_NAME, 't' FROM USER_TABLES UNION ALL "
"SELECT VIEW_NAME, 'v' FROM USER_VIEWS")
res = [TableInfo(row[0].lower(), row[1]) for row in cursor.fetchall()]
schemas = self.connection.settings_dict.get('schemas')
if schemas and len(schemas)>0:
for s in schemas:
cursor.execute("SELECT TABLE_NAME, 't' FROM ALL_TABLES WHERE OWNER = '%s'" %s)
for row in cursor.fetchall():
tbl_name, typ = '.'.join([s,row[0].lower()]), row[1]
try:
# let us check for permission to query
cursor.execute("SELECT * FROM %s WHERE ROWNUM < 1" % tbl_name.upper())
except DatabaseError, e:
pass
else:
res.append(TableInfo(tbl_name, typ))
return res
因为我正在使用gis我必须在 django / contrib / gis / db / backends / oracle / introspection.py中制作一个脏补丁(我不知道是否因数据库问题而需要) 强>
刚刚在 get_geometry_type
的末尾添加了此内容 ...
dim = len(dim)
if dim != 2:
field_params['dim'] = dim
except: # <-- this
pass # <-- this
finally:
cursor.close()
...
答案 4 :(得分:-1)
尝试通过在settings.py的DATABASES变量中添加一个选项来指定search_path,如下所示:
'OPTIONS': {
'options': '-c search_path=myschema'
}
完整的DATABASES变量应为:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mydatabase',
'USER': 'postgres',
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
'OPTIONS': {
'options': '-c search_path=myschema'
}
}
}
之后python migrate inspectdb
应该适用于您的架构