django Ошибка DB2 inspectdb: объект 'NoneType' недопустим - PullRequest
0 голосов
/ 12 марта 2020

моя среда разработки находится в 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

fun c get_table_description задействует код ниже:

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

кажется, я не правильно указали имя таблицы и схемы.

хорошо, мне нужно go спать, очень устал.

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 , я узнаю ответ. описание указанной таблицы, возвращенное из забавного c в introspection.py, реализованного ibm_db_ django, отличается от inspectdb.py в django 2.2.

, поэтому проверьте его с помощью django release история и ibm_db_an go. ibm_db_an go 1.2 выпущен в 2018.4.3, django 2.2 выпущен в 2019.3.

кажется, django 2.2 не поддерживает ibm_db_an go 1.2 (последняя версия)

поэтому я должен был установить django 2.0 вместо этого.

наконец-то это работает !!!.

...