1

我的开发环境位于 python 3.6 和 virtualenv(virtualenv 15.1.0) 中,并且具有以下依赖项:django 2.2 ibm-db 3.0.1 ibm-db-django 1.2.0.0

当我使用“(env_django2) λ python manage.py check”时,它返回“系统检查发现没有问题(0 静音)。” 这不是问题。

但是,当我使用“python manage.py inspectdb --database db2 DEMO.DEMOUSER”时,它返回如下:

(env_django2) λ python manage.py inspectdb --database db2 DEMO.DEMOUSER
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
#   * Rearrange models' order
#   * Make sure each model has one field with primary_key=True
#   * Make sure each ForeignKey has `on_delete` set to the desired behavior.
#   * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models
# Unable to inspect table 'DEMO.DEMOUSER'
# The error was: 'NoneType' object is not subscriptable

这是我的 db2 设置:

 DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'db2':{
        'ENGINE': 'ibm_db_django',
        'NAME': 'test',
        'USER': 'db2inst1',
        'PASSWORD': 'XXXXXX',
        'HOST': 'XX.XXX.XXX.XXX',
        'PORT': 'XXXXX',
        'PCONNECT':True,
    }
}

我已经通过下面这样的编码对其进行了测试,这没有问题。

with connections['db2'].cursor() as cursor:
    cursor.execute("""
                    select * from DEMO.DEMOUSER
                  """)
    columns = [col[0] for col in cursor.description]
    listResult = [dict(zip(columns, row)) for row in cursor.fetchall()]
    print(listResult)

所以我的问题是如何使 inspectdb 工作?

我检查了inspectdb.py,我发现

table_description = connection.introspection.get_table_description(cursor, table_name)
except Exception as e:
    yield "# Unable to inspect table '%s'" % table_name

func get_table_description 将包含以下代码:

sql = "SELECT TYPE FROM SYSIBM.SYSTABLES WHERE CREATOR='%(schema)s' AND NAME='%(table)s'" % {'schema': schema.upper(), 'table': table_name.upper()}

看来我没有正确设置表和模式名称。

好吧,我要睡觉了,很累。

2020.3.13更新…………

所以当我阅读 ibm_db_django\introspection.py 中的代码时,我发现如下:

schema = cursor.connection.get_current_schema() 

这意味着,ibm_db_django 将默认获取模式,这是您在 django 设置文件中设置的用户名。所以在我的例子中,它总是会设置像'db2inst1.DEMO.DEMOUSER'这样的表名。你不能自己改变架构。

据我所知,将模式设置为不可变是不合理的,因为模式和用户在 db2 中与 oracle 不同。每个人都可以使用授予的架构。

因此,我必须像这样更改代码,以便我可以正确设置我的架构:

# change the code below
#schema = cursor.connection.get_current_schema()
print( '-----------change by HK 20200313-----------------')
if len(table_name.split('.')) == 2:
    cursor.connection.set_current_schema(table_name.split('.')[0].upper())
    table_name = table_name.split('.')[1]

schema = cursor.connection.get_current_schema()
print('----------------- HK TEST schema:%s'%schema) 


# change the code below
#cursor.execute( "SELECT * FROM %s FETCH FIRST 1 ROWS ONLY" % qn( table_name ) )
sql = "SELECT * FROM %s FETCH FIRST 1 ROWS ONLY" % ( schema+'.'+table_name )
print('------------ HK TEST LOG:%s'%sql)
cursor.execute( sql )

所以问题已经解决了,但是,另一个出现了!当我输入命令“python manage.py inspectdb --database db2 DEMO.DEMOUSER”时,它显示如下:

class DemoDemouser(models.Model):
Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "D:\MyProject\python\django-sample\env_django2\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "D:\MyProject\python\django-sample\env_django2\lib\site-packages\django\core\management\__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\MyProject\python\django-sample\env_django2\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\MyProject\python\django-sample\env_django2\lib\site-packages\django\core\management\base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "D:\MyProject\python\django-sample\env_django2\lib\site-packages\django\core\management\commands\inspectdb.py", line 34, in handle
    for line in self.handle_inspection(options):
  File "D:\MyProject\python\django-sample\env_django2\lib\site-packages\django\core\management\commands\inspectdb.py", line 102, in handle_inspection
    column_name = row.name
AttributeError: 'list' object has no attribute 'name'

检查inspectdb.py,我找到了答案。从 ibm_db_django 实现的 introspection.py 中的 func 返回的指定表的描述与 django 2.2 中的 inspectdb.py 不同。

所以用 django 发布历史和 ibm_db_ango 检查它。ibm_db_ango 1.2 于 2018.4.3 发布,django 2.2 于 2019.3 发布。

似乎 django 2.2 不支持 ibm_db_ango 1.2(最新版本)

因此我不得不安装 django 2.0。

终于成功了!!!

4

0 回答 0