5

我想对 Oracle 数据库运行inspectdb 。我使用的用户帐户是拥有 0 个表的只读用户。但是,它可以访问包含所有表的模式。使用时如何指定架构inspectdb

目前,我的命令是:python manage.py inspectdb --database "oradb" > test_model.py

这只会输出一个带有from django.db import models.

4

5 回答 5

4

关于 Oracle 支持,César 的回答是正确的。django\db\backends\oracle\introspection.py但是,我能够通过在两个地方进行修改来生成粗略的模型。

cursor.execute将行更改为get_table_list

cursor.execute("SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'OTHERSCHEMA'")

将第一行中的user_table_colsto更改为: ALL_TAB_COLUMNScursor.executeget_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
于 2012-08-06T19:17:20.317 回答
1

问题是 Django 的inspectdb不支持 Oracle。从文档:

inspectdb 适用于 PostgreSQL、MySQL 和 SQLite。外键检测仅适用于 PostgreSQL 和某些类型的 MySQL 表。

--database 选项可用于指定要自省的数据库。

于 2012-08-06T17:27:10.963 回答
1

如果有人遇到这个线程:安迪的建议 + 我还更改了 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
于 2016-01-20T14:19:34.030 回答
0

我的两分钱。(django 版本 1.9.7 + django GIS 扩展)

根据 Andy 和 Mirek Simek 的建议,我进一步修改:

在settings.py的数据库配置中添加了“模式”

    ...
    '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()
    ...
于 2016-10-19T13:19:31.587 回答
-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应该适用于您的架构

于 2016-02-05T15:04:29.543 回答