Модель Django принудительно использует имена столбцов db_column с заглавной буквы

#python #sql #django #oracle

#python #sql #django #Oracle

Вопрос:

Я создаю модель Django, которая считывает данные из базы данных Oracle SQL. В таблице, из которой считывается модель, некоторые столбцы имеют смешанные регистры и пробелы, то есть «Region» и «Foo Bar». Так

 SELECT "Region", "Foo Bar" FROM some_table
 

это совершенно справедливо для БД. Модель Django явно считывает эти столбцы, используя db_column поле,

 class SomeModel(models.Model):
  region = models.CharField(max_length=100, db_column="Region")
  foo_bar = models.CharField(max_length=100, db_column="Foo Bar")
 

Однако, когда Django переходит к базе данных, я получаю сообщение об ошибке

 ORA-00904: invalid identifier: "some_table"."FOO BAR"
 

из-за того, что имя столбца пишется с заглавной буквы где-то в процессе. Есть ли какой-нибудь способ заставить Django сохранить смешанный регистр с точки зрения Django, не изменяя имена столбцов на стороне db?

Я пробовал: db_column="'Foo Bar'" , '"Foo Bar"' , ""Foo Bar"" , ни один из них, похоже, не интерпретирует строку буквально и в верхнем регистре.

Спасибо! Приветствуются хакерские обходные пути.

Комментарии:

1. Это пахнет ошибкой, особенно если вы посмотрите на этот тест . Какую версию вы используете? Возможно, это было исправлено в более поздней версии.

2. Кажется, это сделано специально для Oracle: посмотрите код, который это делает

Ответ №1:

При использовании базы данных Oracle Django изменяет имена столбцов на прописные (см. Код).

Решить это непросто. Вероятно, вам лучше всего расширить Oracle, чтобы переопределить эту функциональность. Для этого вам нужно создать модуль для вашего нового бэкэнда с именем файла base.py . Содержимое которого будет выглядеть как:

 from django.db.backends.oracle.base import DatabaseWrapper as OracleWrapper
from django.db.backends.oracle.operations import DatabaseOperations as OracleOperations

class DatabaseOperations(OracleOperations):
    def quote_name(self, name):
        # Modified version that doesn't apply upper to the quoted column names
        if not name.startswith('"') and not name.endswith('"'):
            name = '"%s"' % truncate_name(name.upper(), self.max_name_length())
        return name.replace('%', '%%')


class DatabaseWrapper(OracleWrapper):
    ops_class = DatabaseOperations
 

DatabaseWrapper это специальное имя, и вы не должны его изменять. После этого вам нужно установить модуль в качестве вашего ядра базы данных; вы должны перейти к родительскому модулю (т. Е., Если путь к файлу myapp/backends/custom/base.py указан, вы должны установить его myapp.backends.custom ).

У меня нет времени на правильное тестирование этого кода (на самом деле у меня нет базы данных Oracle для игры), но именно так создаются серверные части ГИС, поэтому они должны быть достаточно безопасными (но могут потребоваться некоторые другие вещи).).