Базы данных

Django официально поддерживает следующие базы данных:

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

Django пытается включить как можно больше функций для всех типов баз данных. Однако не все типы баз данных созданы равными, и нам пришлось принять проектные решения о том, какие функции включить и на какие допущения можно безопасно полагаться.

В этом файле описаны некоторые функции, которые могут иметь отношение к использованию Django. Он не предназначен для замены документации по серверу или справочных руководств.

Общие замечания

Постоянные соединения

Постоянные соединения избавляют от необходимости повторно устанавливать соединение с базой данных для каждого запроса. Они контролируются настройкой, CONN_MAX_AGE которая определяет максимальное время жизни соединения. Этот параметр можно установить независимо для каждой базы данных.

По умолчанию 0 сохраняется историческое поведение закрытия соединения с базой данных в конце каждого запроса. Чтобы разрешить постоянные соединения, задайте CONN_MAX_AGE положительное целое число секунд. Чтобы сделать постоянные соединения неограниченными по времени, установите для него значение None .

Управление подключениями

Django открывает соединение с базой данных по первому запросу базы данных. Это соединение остается открытым и повторно используется для последующих запросов. Django закрывает соединение, как только истечет установленный срок CONN_MAX_AGE или соединение больше не будет использоваться.

В деталях, Django автоматически открывает соединение с базой данных всякий раз, когда это необходимо, и его еще нет - либо потому, что это первое соединение, либо потому, что предыдущее соединение. был закрыт.

Перед каждым запросом к базе данных Django закрывает соединение, если достигнуто ограничение по времени. Если ваша база данных завершает незанятые соединения через определенное время, вы должны установить для него CONN_MAX_AGE более низкое значение, чтобы Django не пытался использовать соединение, которое было прервано сервером базы данных (эта проблема не может повлиять на чем сайты с очень низкой посещаемостью).

В конце каждого запроса к базе данных Django закрывает соединение, если соединение достигло ограничения по времени или если оно находится в состоянии фатальной ошибки. Если при обработке запросов возникли какие-либо ошибки базы данных, Django проверяет, работает ли соединение, и закрывает его, если это не так. Таким образом, ошибки базы данных влияют не более чем на один запрос; если соединение становится непригодным для использования, следующий запрос получает новое соединение.

Предостережения

Поскольку каждый поток управляет своим собственным подключением, база данных должна поддерживать как минимум столько одновременных подключений, сколько существует рабочих потоков для Django.

Иногда большинство представлений не имеют доступа к определенной базе данных, например, потому что это база данных внешней системы или через кеширование. В этом случае следует установить CONN_MAX_AGE низкое значение или даже значение 0 , поскольку нет смысла поддерживать соединение, которое вряд ли будет использоваться повторно. Это поможет сохранить небольшое количество одновременных подключений к этой базе данных.

Сервер разработки создает новый поток для каждого обрабатываемого запроса, сводя на нет эффект постоянных подключений. Не активируйте их во время разработки.

Когда Django подключается к базе данных, он устанавливает соответствующие параметры в зависимости от типа используемой базы данных. Если вы включаете постоянные соединения, эта фаза настройки не повторяется для каждого запроса. Если вы меняете такие параметры, как уровень изоляции соединения или часовой пояс, вы должны либо восстановить Django до настроек по умолчанию в конце каждого запроса, либо принудительно установить соответствующее значение перед каждым запросом, либо отключить соединения. упорный.

Характер кодирования ¶

Django предполагает, что все базы данных используют кодировку UTF-8. Использование других кодировок может привести к неожиданному поведению, например к ошибкам базы данных «слишком длинное значение» для данных, допустимых в Django. См. Примечания к базе данных ниже, чтобы узнать, как правильно настроить базу данных.

Примечания к PostgreSQL

Django поддерживает PostgreSQL 9.5 и новее. Требуется psycopg2 2.5.4 или новее, хотя рекомендуется использовать более новую версию.

Параметры подключения PostgreSQL

Подробнее HOST см.

Оптимизация конфигурации PostgreSQL

Для подключения к базам данных Django необходимы следующие параметры:

  • client_encoding : 'UTF8' ,
  • default_transaction_isolation : по умолчанию или значение, определенное в параметрах подключения (см. ниже),'read committed'
  • timezone :
    • когда USE_TZ есть True , 'UTC' по умолчанию, или TIME_ZONE значение , установленное для подключения,
    • когда USE_TZ есть False , значение глобальной TIME_ZONE настройки.

Если эти параметры уже имеют правильные значения, Django не придется предоставлять их для каждого нового соединения, что немного улучшает производительность. Вы можете настроить их напрямую postgresql.conf или более удобно для каждого пользователя базы данных с помощью ALTER ROLE .

Django отлично работает без этой оптимизации, но каждое новое соединение будет делать еще несколько запросов для установки этих параметров.

Уровень изоляции

Как и в случае с самим PostgreSQL, Django по умолчанию использует "уровень изоляции " . Если вам нужен более высокий уровень изоляции, такой как или , установите его в части конфигурации базы данных :READ COMMITTED REPEATABLE READ SERIALIZABLE OPTIONS DATABASES

import psycopg2.extensions

DATABASES = {
    # ...
    'OPTIONS': {
        'isolation_level': psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE,
    },
}

Заметка

При более высоких уровнях изоляции ваше приложение должно быть готово обрабатывать исключения, которые генерируются во время сбоев сериализации. Эта опция предназначена для опытных пользователей.

Указатель столбцов varchar и text

Когда вы заполняете db_index=True поля шаблона, Django обычно генерирует только одно . Однако, если тип поля базы данных - или (например, для полей типа , или ), то Django создает дополнительный индекс, который использует соответствующий класс операторов PostgreSQL для столбца. Этот дополнительный индекс необходим для правильного функционирования поиска, использующего оператор SQL , как и поиск с использованием и .CREATE INDEX varchar text CharField FileField TextField LIKE contains startswith

Операция миграции для добавления расширений

Если вам нужно добавить расширение PostgreSQL (например hstore , postgis и т. Д.) С помощью миграции, используйте операцию CreateExtension .

Курсоры на стороне сервера

При использовании QuerySet.iterator() Django открывает курсор на стороне сервера . По умолчанию PostgreSQL предполагает, что будут получены только первые 10% результатов запроса курсора. Планировщик запросов тратит меньше времени на планирование запроса и начинает быстрее возвращать результаты, но он также может снизить производительность, если будет получено более 10% результатов. Предположения PostgreSQL о количестве строк, полученных из запроса курсора, контролируются параметром cursor_tuple_fraction .

Массовые транзакции и серверные курсоры

Использование пула соединений в режиме пула транзакций (например, PgBouncer ) требует отключения серверных курсоров для этого соединения.

Курсоры на стороне сервера зависят от соединения и остаются открытыми в конце транзакции, когда они AUTOCOMMIT стоят True . Следующая транзакция может потребовать дополнительных результатов от серверного курсора. В режиме объединения транзакций нет гарантии, что последующие транзакции будут повторно использовать одно и то же соединение. Если используется другое соединение, возникает ошибка, когда транзакция обращается к курсору на стороне сервера, потому что эти типы курсоров доступны только для соединения, в котором они были созданы.

Одно из решений - отключить серверные курсоры для подключения DATABASES , установив DISABLE_SERVER_SIDE_CURSORS значение True .

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

Другой вариант - обернуть каждый QuerySet из курсоров на стороне сервера в блок atomic() , так как это отключает режим autocommit на время транзакции. Таким образом, курсор на стороне сервера будет активен только на время транзакции.

Ручное указание значений первичного ключа с автоинкрементом

Django использует тип данных PostgreSQL SERIAL для хранения первичных ключей автоинкремента. Столбец SERIAL заполняется значениями в последовательности, которая отслеживает следующее доступное значение. Присвоение значения полю автоинкремента вручную не приводит к обновлению последовательности поля, что в дальнейшем может вызвать конфликт. например

>>> from django.contrib.auth.models import User
>>> User.objects.create(username='alice', pk=1)
<User: alice>
>>> # The sequence hasn't been updated; its next value is 1.
>>> User.objects.create(username='bob')
...
IntegrityError: duplicate key value violates unique constraint
"auth_user_pkey" DETAIL:  Key (id)=(1) already exists.

Если вам нужно указать такие значения, сбросьте последовательность, чтобы избежать повторного использования значения, которое уже есть в таблице. Команда администрирования sqlsequencereset генерирует команды SQL, которые это делают.

Тестовые модели базы данных

Этот параметр может использоваться TEST['TEMPLATE'] для указания шаблона (например 'template0' ), из которого создается тестовая база данных.

Ускорение выполнения теста с помощью временных настроек

Вы можете ускорить выполнение теста, настроив Loss-Accepted PostgreSQL .

Предупреждение

Это опасно: ваша база данных будет более подвержена потере или повреждению данных в случае сбоя сервера или отключения электроэнергии. Используйте это только на машинах для разработки, где вы можете легко восстановить все базы данных в кластере.

Заметки MariaDB

Новое в Django 3.0.

Django поддерживает MariaDB 10.2 и выше.

Чтобы использовать MariaDB, используйте движок MySQL, который является общим для них обоих. См. Примечания к MySQL для получения более подробной информации.

Примечания к MySQL

Поддерживаемые версии

Django поддерживает MySQL версии 5.6 и новее.

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

Django ожидает, что база данных примет Unicode (кодировка UTF-8) и делегирует ей ответственность за выполнение транзакций и ссылочную целостность. Важно знать, что эти последние два аспекта фактически не применяются MySQL при использовании механизма хранения MyISAM, см. Следующий раздел.

Механизмы хранения

MySQL имеет несколько механизмов хранения . Вы можете изменить механизм хранения по умолчанию в конфигурации сервера.

Механизм хранения MySQL по умолчанию - InnoDB . Этот механизм полностью транзакционный и поддерживает ссылки на внешние ключи. Это рекомендуемый выбор. Однако счетчик автоматического увеличения InnoDB теряется при перезапуске MySQL, потому что он не сохраняет значение, AUTO_INCREMENT а пересчитывает его как «max (id) +1». Это может привести к неправильному повторному использованию значений AutoField .

Основные недостатки MyISAM заключаются в том, что он не поддерживает транзакции и не проверяет ограничения внешнего ключа.

Драйверы MySQL DB API

MySQL предлагает несколько драйверов, которые реализуют API базы данных Python, описанный в PEP 249 :

  • mysqlclient - это собственный драйвер. Это рекомендуемый выбор .
  • MySQL Connector / Python - это чистый драйвер Python, написанный Oracle, который не требует клиентской библиотеки MySQL или других модулей Python за пределами стандартной библиотеки.

Эти драйверы учитывают конкуренцию между потоками выполнения (потокобезопасность) и управляют группировкой соединений (пул).

Помимо драйвера DB API, Django нужен адаптер для доступа к драйверам базы данных из ORM. Django предоставляет адаптер для mysqlclient, а MySQL Connector / Python включает собственный .

mysqlclient

Django требует mysqlclient 1.4.0 или новее.

Коннектор MySQL / Python

MySQL Connector / Python доступен на этой странице загрузки . Адаптер Django доступен в версиях 1.1.X и новее. Он может не поддерживать последнюю версию Django.

Определения часовых поясов

Если вы планируете использовать поддержку часовых поясов Django, используйте mysql_tzinfo_to_sql для загрузки таблиц часовых поясов в базу данных MySQL. Это нужно сделать только один раз для каждого сервера MySQL, а не для каждой базы данных.

Создание базы данных

Вы можете создать базу данных с помощью инструментов командной строки и этой команды SQL:

CREATE DATABASE <dbname> CHARACTER SET utf8;

Это гарантирует, что все таблицы и столбцы по умолчанию используют кодировку UTF-8.

Параметры сортировки

Метод сортировки («сопоставление») столбца определяет порядок, в котором сортируются данные, а также сравнение строк на равенство. Этот параметр может быть определен на уровне базы данных, а также по таблице и по столбцу. Это полностью задокументировано в документации MySQL. Во всех случаях метод сортировки определяется прямым изменением таблиц базы данных; Django не предоставляет возможности сделать это на уровне определения модели.

По умолчанию в базе данных UTF-8 MySQL использует сопоставление utf8_general_ci . В результате все сравнения строк на равенство выполняются без учета регистра. То есть «Fred» и «freD» считаются эквивалентными для базы данных. Если вы наложили уникальное ограничение на поле, было бы недопустимо вставлять и «aa», и «AA» в этот же столбец, поскольку их сравнение показывает, что они одинаковы (и, следовательно, не уникальный) с параметрами сортировки по умолчанию. Если вы хотите выполнить сравнение с учетом регистра в конкретном столбце или таблице, измените параметры сортировки для столбца или таблицы на utf8_bin .

Обратите внимание, что в соответствии с наборами символов MySQL Unicode сравнения с сопоставлением utf8_general_ci выполняются быстрее, но немного менее корректны, чем сравнения с utf8_unicode_ci . Если это приемлемо для вашего приложения, лучше использовать, utf8_general_ci потому что это быстрее. В противном случае (например, если вам нужен порядок словаря немецкого языка) используйте, utf8_unicode_ci потому что это сопоставление более правильное.

Предупреждение

Подчиненные формы шаблона проверяют уникальные поля с учетом регистра. Таким образом, при использовании сортировки базы данных без учета регистра подформы, содержащие уникальные значения полей, которые отличаются только своим регистром, успешно пройдут проверку, но во время проверки. запись по save() , произойдет исключение IntegrityError .

Подключение к базе данных

См. Документацию по настройкам .

Параметры подключения используются в таком порядке:

  1. OPTIONS ,
  2. NAME , USER , PASSWORD , HOST , PORT
  3. Файлы опций MySQL.

Другими словами, если вы установите имя базы данных в OPTIONS , это определение имеет приоритет NAME , что само по себе будет иметь приоритет над любым значением в файле опций MySQL .

Вот пример конфигурации, в которой используется файл опций MySQL:

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'read_default_file': '/path/to/my.cnf',
        },
    }
}


# my.cnf
[client]
database = NAME
user = USER
password = PASSWORD
default-character-set = utf8

Могут быть полезны некоторые другие параметры подключения MySQLdb , например ssl , init_command или sql_mode .

Определение sql_mode

Начиная с MySQL 5.7 и для новых установок MySQL 5.6 значение параметра по умолчанию sql_mode содержит STRICT_TRANS_TABLES . Эта опция превращает предупреждения в ошибки, когда данные усекаются во время вставки. Django настоятельно рекомендует включить строгий режим для MySQL, чтобы избежать потери данных ( STRICT_TRANS_TABLES или STRICT_ALL_TABLES ).

ЕСЛИ вам нужно настроить режим SQL, vuos может установить эту переменную, sql_mode как и любой другой параметр MySQL: либо в файле конфигурации, либо с помощью строки в части конфигурации базы данных в .'init_command': "SET sql_mode='STRICT_TRANS_TABLES'" OPTIONS DATABASES

Уровень изоляции

При работе с конкурентной нагрузкой транзакции базы данных из разных сеансов (например, отдельные потоки, обрабатывающие разные запросы) могут взаимодействовать друг с другом. На эти взаимодействия влияет уровень изоляции транзакции каждого сеанса. Можно установить уровень изоляции транзакции соединения с ключом 'isolation_level' части OPTIONS конфигурации базы данных в DATABASES . Допустимые значения для этого ключа - четыре стандартных уровня изоляции:

  • 'read uncommitted'
  • 'read committed'
  • 'repeatable read'
  • 'serializable'

или None использовать уровень изоляции, настроенный на сервере. Однако Django лучше работает с (выбор Django по умолчанию), чем с MySQL по умолчанию . Возможна потеря данных с уровнем . В частности, вы можете столкнуться со случаями, когда возникает исключение, но объект не появляется в будущих вызовах .read committed repeatable read repeatable read get_or_create() IntegrityError get()

Создание таблиц

Когда Django генерирует схему, он не указывает механизм хранения, поэтому таблицы будут созданы с механизмом хранения по умолчанию для вашего сервера базы данных. Самое простое решение - установить желаемый механизм в качестве механизма хранения по умолчанию для вашего сервера базы данных.

Если вы пользуетесь услугами хостинга и не можете изменить механизм хранения по умолчанию на своем сервере, у вас есть несколько вариантов.

  • После создания таблиц запустите команду SQL, чтобы преобразовать таблицу в новый механизм хранения (например, InnoDB):ALTER TABLE

    ALTER TABLE <tablename> ENGINE=INNODB;
    

    Это может быть утомительно, если у вас много таблиц.

  • Другая возможность - использовать опцию init_command MySQLdb перед созданием таблиц:

    'OPTIONS': {
       'init_command': 'SET default_storage_engine=INNODB',
    }
    

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

Имена таблиц

Некоторые известные проблемы , даже в последних версиях MySQL, могут вызывать изменение имени таблицы, когда определенные операторы SQL выполняются при определенных условиях. Рекомендуется по возможности использовать имена таблиц в нижнем регистре, чтобы избежать проблем, которые могут возникнуть в результате такого поведения. Django использует имена таблиц в нижнем регистре, когда автоматически генерирует имена таблиц из моделей, поэтому это нужно учитывать, особенно если вы переопределяете имя таблицы с помощью параметра db_table .

Точки сохранения

И ORM Django, и MySQL (когда используется механизм хранения InnoDB) поддерживают точки сохранения базы данных.

Если вы используете механизм хранения MyISAM, вы получите ошибки, созданные базой данных, если попытаетесь использовать методы API транзакций точки сохранения . В самом деле, поскольку обнаружение механизма хранения таблицы или базы данных MySQL является очень затратной операцией в ресурсах, было решено не преобразовывать эти методы динамически в нейтральные методы, основанные на этом виде. обнаружение.

Примечания по отдельным полям

Поля символов

Любые поля, которые хранятся с VARCHAR типами столбцов, могут иметь max_length ограничение до 255 символов, если вы используете unique=True это поле. Это касается CharField , SlugField . См. Дополнительную информацию в документации MySQL .

Пределы поля

MySQL может индексировать только первые N символов столбца BLOB или TEXT . Поскольку у TextField него нет определенной длины, пометить такое поле значком невозможно unique=True . MySQL выдаст ошибку: «Столбец BLOB / TEXT« <db_column> »используется в спецификации ключа без длины ключа».

Поддержка дробных секунд для времени и полей даты / времени

Начиная с версии 5.6.4, MySQL может хранить доли секунды, если определения столбцов содержат соответствующее указание (например, DATETIME(6) ). В предыдущих версиях это вообще не поддерживалось.

Сам Django не будет обновлять существующие столбцы, чтобы включать доли секунд, если сервер базы данных поддерживает это. Если вы хотите активировать их в существующей базе данных, вам нужно вручную обновить столбец в базе данных, выполнив такую ​​команду, как:

ALTER TABLE `your_table` MODIFY `your_datetime_column` DATETIME(6)

или с помощью операции RunSQL в миграции данных .

Столбцы TIMESTAMP

Если вы используете существующую базу данных, содержащую столбцы TIMESTAMP , вы должны установить ее, чтобы избежать повреждения данных. сопоставляет эти столбцы с полями, и если вы включите поддержку часового пояса, MySQL и Django попытаются преобразовать значения из UTC в местное время.USE_TZ = False inspectdb DateTimeField

Блокировка ряда с помощью QuerySet.select_for_update()

MySQL и MariaDB не поддерживают некоторые параметры оператора . Если используется с неподдерживаемым параметром, создается исключение .SELECT ... FOR UPDATE select_for_update() NotSupportedError

вариант MariaDB MySQL
SKIP LOCKED   Х (≥8.0.1)
NOWAIT Х (≥10,3) Х (≥8.0.1)
OF    

При использовании select_for_update() с MySQL обязательно отфильтруйте запрос по крайней мере с одним полем, содержащимся в ограничениях уникальности, или только с полями, имеющими индексы. В противном случае будет получена исключительная блокировка записи для всей таблицы в течение всей транзакции.

Автоматический повторный ввод может привести к неожиданным результатам

При выполнении запроса к строковому типу, но с целочисленным значением, MySQL переводит типы всех значений в таблицу в целые числа перед выполнением сравнения. Если таблица содержит значение 'abc' , 'def' и поиски запроса , два ряда будет совпадать. Таким же образом соответствует значение . Вот почему поля строкового типа, включенные в Django, всегда приводят значение к строке, прежде чем использовать ее в запросе.WHERE macolonne=0 WHERE macolonne=1 'abc1'

Если вы реализуете пользовательские модели поля , которые наследуют непосредственно из Field , переопределения get_prep_value() или использования RawSQL , extra() или raw() , вы должны убедиться , что вы выполняете соответствующие подкрепления типа.

Примечания к SQLite

Django поддерживает SQLite версии 3.8.3 и новее.

SQLite представляет собой отличную альтернативу для разработки приложений, которые в основном предназначены только для чтения или требуют установки меньшего размера. Однако, как и в случае со всеми серверами баз данных, есть несколько специфических отличий SQLite, о которых следует помнить.

Поиск частей строк и чувствительности к регистру

Для всех версий SQLite наблюдается неинтуитивное поведение при попытке сопоставить определенные типы строк. Это поведение срабатывает при использовании фильтров iexact или contains в QuerySets. Поведение делится на два случая:

1. Для сопоставления подстрок все совпадения выполняются без учета регистра. Это фильтр, который filter(name__contains="aa") будет соответствовать имени "Aabb" .

2. Для строк, содержащих символы вне диапазона ASCII, все точные совпадения строк выполняются с учетом регистра, даже если в запрос передаются параметры без учета регистра. Таким образом, в этих случаях iexact фильтр будет вести себя точно так же, как и exact фильтр.

На sqlite.org есть несколько обходных путей , но они не используются механизмом SQLite по умолчанию Django, так как это потребовало бы определенных трудностей для надежной работы. Таким образом, Django демонстрирует поведение SQLite по умолчанию, и вы должны знать об этом при фильтрации подстрок или строк без учета регистра.

Обработка десятичных знаков

SQLite не имеет внутреннего типа десятичного числа. Десятичные значения преобразуются в тип данных REAL (8-байтовое число с плавающей запятой IEEE), как показано в документации по типам данных SQLite , поэтому арифметические операции с десятичными числами с плавающей запятой не выполняются. обработано правильно (проблемы с округлением).

Ошибки «База данных заблокирована»

Предполагается, что SQLite является легкой базой данных и поэтому не может обрабатывать высокий уровень параллелизма. Ошибки указывают на то, что приложение испытывает более высокую конкуренцию, чем может обрабатывать его конфигурация по умолчанию. Эта ошибка означает, что процесс или поток имеют монопольную блокировку соединения с базой данных, а другому потоку пришлось слишком долго ждать снятия блокировки.OperationalError: database is locked sqlite

Адаптер Python SQLite имеет значение тайм-аута по умолчанию, которое определяет максимальное время ожидания разблокировки другого потока до истечения времени ожидания с ошибкой .OperationalError: database is locked

Если вы получили эту ошибку, вы можете решить проблему следующим образом:

  • Переход на другой движок базы данных. В какой-то момент SQLite действительно становится слишком легким для реальных приложений, и такая ошибка параллелизма указывает на то, что точка была достигнута.

  • Переписать код, чтобы уменьшить параллелизм и сделать транзакции базы данных как можно короче.

  • Увеличьте значение срока действия по умолчанию, установив параметр базы данных timeout :

    'OPTIONS': {
        # ...
        'timeout': 20,
        # ...
    }
    

    Это заставит SQLite ждать немного дольше, прежде чем возникнет ошибка «база данных заблокирована»; но поэтому основная проблема не решена.

QuerySet.select_for_update() не поддерживается

SQLite не поддерживает синтаксис . Вызов этого метода ни на что не влияет.SELECT ... FOR UPDATE

Стиль параметра "pyformat" в необработанных запросах не поддерживается

Для большинства движков необработанные ( Manager.raw() или cursor.execute() ) запросы могут использовать стиль параметра "pyformat", где заполнители в запросе записываются как, '%(nom)s' а параметры передаются как словарь, а не список. SQLite не поддерживает этот синтаксис.

Изоляция при использовании QuerySet.iterator()

В разделе «Изоляция в SQLite» описаны особые ситуации при изменении таблицы при ее просмотре с помощью QuerySet.iterator() . Если строка добавляется, изменяется или уничтожается в цикле, эта строка может появляться или не появляться, или даже появляться дважды в последующих результатах от итератора. Ваш код должен справиться с этим.

Включение расширения JSON1 на SQLite

Для использования JSONField в SQLite вам необходимо включить расширение JSON1 в sqlite3 библиотеке Python . Если расширение не включено в вашей установке, появится системная ошибка ( fields.E180 ).

Чтобы включить расширение JSON1, следуйте инструкциям на вики-странице .

Примечания к Oracle

Django поддерживает версии 12.2 и новее сервера баз данных Oracle . Требуется версия драйвера cx_Oracle Python не ниже 6.0 .

Чтобы команда работала, пользователь базы данных Oracle должен иметь права на выполнение следующих команд:python manage.py migrate

  • СОЗДАТЬ ТАБЛИЦУ
  • СОЗДАТЬ ПОСЛЕДОВАТЕЛЬНОСТЬ
  • СОЗДАТЬ ПРОЦЕДУРУ
  • СОЗДАТЬ ТРИГГЕР

Для запуска набора тестов проекта пользователю обычно требуются следующие дополнительные права :

  • СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ
  • ИЗМЕНИТЬ ПОЛЬЗОВАТЕЛЯ
  • УДАЛИТЬ ПОЛЬЗОВАТЕЛЯ
  • СОЗДАТЬ ТАБЛИЧНОЕ ПРОСТРАНСТВО
  • DROP TABLESPACE
  • СОЗДАТЬ СЕССИЮ С ОПЦИЕЙ АДМИНИСТРАТОРА
  • СОЗДАТЬ ТАБЛИЦУ С ОПЦИЕЙ АДМИНИСТРАТОРА
  • СОЗДАТЬ ПОСЛЕДОВАТЕЛЬНОСТЬ С ОПЦИЕЙ АДМИНИСТРАТОРА
  • СОЗДАТЬ ПРОЦЕДУРУ С ОПЦИЕЙ АДМИНИСТРАТОРА
  • СОЗДАТЬ ТРИГГЕР С ОПЦИЕЙ АДМИНИСТРАТОРА

Хотя роль RESOURCE имеет необходимые привилегии , , и , и пользователь с может предоставить привилегию , что пользователь не может предоставить индивидуальные привилегии (например. ), Так что , как правило , не достаточно запустить тесты.CREATE TABLE CREATE SEQUENCE CREATE PROCEDURE CREATE TRIGGER RESOURCE WITH ADMIN OPTION RESOURCE CREATE TABLE RESOURCE WITH ADMIN OPTION

Некоторые наборы тестов также создают представления или материализованные представления; для выполнения этого, пользователь также нуждается и привилегии . Это особенно необходимо для собственного набора тестов Django.CREATE VIEW WITH ADMIN OPTION CREATE MATERIALIZED VIEW WITH ADMIN OPTION

Все эти привилегии включены в роль администратора базы данных, что подходит для частной базы данных разработки.

Oracle Database Engine использует пакеты SYS.DBMS_LOB и SYS.DBMS_RANDOM , таким образом, пользователь должен иметь права на выполнение для него. Обычно он доступен по умолчанию для всех пользователей, но если это не так, вы должны назначить такие разрешения:

GRANT EXECUTE ON SYS.DBMS_LOB TO user;
GRANT EXECUTE ON SYS.DBMS_RANDOM TO user;

Подключение к базе данных

Чтобы подключиться с использованием имени службы базы данных Oracle, файл settings.py должен выглядеть примерно так:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': '',
        'PORT': '',
    }
}

В этом случае, вы должны оставить два ключа HOST и опорожнить PORT . Однако, если вы не используете файл tnsnames.ora или аналогичный метод именования и хотите подключиться с использованием SID («xe» в этом примере), заполните оба HOST и PORT , например:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': 'dbprod01ned.mycompany.com',
        'PORT': '1540',
    }
}

Либо заполните оба ключа, HOST но PORT оставьте оба пустыми. Django использует другой дескриптор подключения в зависимости от этого выбора.

Полный DSN и Easy Connect

Можно использовать полную цепочку DSN или Easy Connect, NAME если оба HOST и PORT пустые. Этот формат необходим, например, при использовании RAC или подключаемых баз данных без tnsnames.ora .

Пример канала Easy Connect

'NAME': 'localhost:1521/orclpdb1',

Пример полной цепочки DSN

'NAME': (
    '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))'
    '(CONNECT_DATA=(SERVICE_NAME=orclpdb1)))'
),

Вариант с резьбой

Если вы планируете запускать Django в многопоточной (многопоточной) среде, например, с Apache и модулем MPM по умолчанию в любой современной операционной системе), вам следует установить свой True параметр threaded конфигурации База данных Oracle:

'OPTIONS': {
    'threaded': True,
},

Если вы этого не сделаете, вы рискуете получить посадку и другое странное поведение.

ВСТАВИТЬ… ВОЗВРАЩЕНИЕ В

По умолчанию механизм Oracle использует предложение для эффективного получения значения поля при вставке новых строк. Такое поведение может привести к ошибкам в некоторых конкретных конфигурациях, например, при вставке в удаленную таблицу или в представление с триггером . Предложение можно отключить, установив для параметра конфигурации базы данных значение :RETURNING INTO AutoField DatabaseError INSTEAD OF RETURNING INTO use_returning_into False

'OPTIONS': {
    'use_returning_into': False,
},

В этом случае механизм Oracle использует SELECT отдельный запрос для получения значений AutoField .

Вопросы по именованию

Oracle устанавливает ограничение на длину имен в 30 символов. Чтобы соответствовать этому, механизм усекает идентификаторы базы данных по мере необходимости, заменяя последние четыре символа усеченного имени воспроизводимым значением хеш-функции MD5. Вдобавок движок преобразует все идентификаторы базы данных в верхний регистр.

Чтобы предотвратить эти преобразования (которые обычно необходимы только при работе с существующими базами данных или когда вам нужен доступ к таблицам, принадлежащим другим пользователям), заключите значение в db_table кавычки:

class LegacyModel(models.Model):
    class Meta:
        db_table = '"name_left_in_lowercase"'

class ForeignModel(models.Model):
    class Meta:
        db_table = '"OTHER_USER"."NAME_ONLY_SEEMS_OVER_30"'

Имена в кавычках также могут использоваться с другими механизмами баз данных, поддерживаемыми Django; но эти цитаты действуют только на Oracle.

При запуске может возникнуть migrate ошибка, ORA-06552 если определенные ключевые слова Oracle используются в качестве имен полей модели или в качестве значения параметра db_column . Django заключает все идентификаторы, используемые в запросах, в кавычки, чтобы предотвратить большинство подобных проблем, но эта ошибка все равно может возникать, когда в качестве имени столбца используется тип данных Oracle. В частности, стараются избегать использования имен date , timestamp , number или float как имена полей.

NULL и пустые строки

Django обычно предпочитает использовать пустую строку ( '' ) NULL , но Oracle рассматривает эти два значения как одно и то же. Чтобы обойти это, механизм Oracle игнорирует явную опцию null для полей, где пустая строка является возможным значением, и генерирует операторы SQL как если бы null=True . При чтении из базы данных Django предполагает, что значение NULL в одном из этих полей на самом деле является пустой строкой, и данные автоматически преобразуются в соответствии с этим принципом.

Пределы поля

Механизм Oracle хранит поля TextFields в столбцах NCLOB . Oracle накладывает некоторые ограничения на использование таких столбцов LOB в целом:

  • Столбцы больших объектов нельзя использовать в качестве первичных ключей.
  • Столбцы больших объектов нельзя использовать в индексах.
  • Столбцы больших объектов нельзя использовать в списке . Это означает, что попытка использовать метод для модели, содержащей столбцы, приведет к ошибке вместе с предотвращением включения столбцов в список .SELECT DISTINCT QuerySet.distinct TextField ORA-00932``avec Oracle. Pour contourner ce problème, utilisez la méthode ``QuerySet.defer distinct() TextField SELECT DISTINCT

Создание подкласса интегрированного движка базы данных

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

Представьте, например, что вам нужно изменить одну функцию базы данных. Во-первых, нужно создать новый каталог, содержащий модуль base . например

mysite/
    ...
    mydbengine/
        __init__.py
        base.py

Модуль base.py должен содержать именованный класс DatabaseWrapper , наследующий существующий механизм от модуля django.db.backends . Вот пример подкласса движка PostgreSQL с целью изменения функциональности класса allows_group_by_selected_pks_on_model :

mysite / mydbengine / base.py
from django.db.backends.postgresql import base, features

class DatabaseFeatures(features.DatabaseFeatures):
    def allows_group_by_selected_pks_on_model(self, model):
        return True

class DatabaseWrapper(base.DatabaseWrapper):
    features_class = DatabaseFeatures

Наконец, вы должны указать значение DATABASE-ENGINE в вашем файле settings.py :

DATABASES = {
    'default': {
        'ENGINE': 'mydbengine',
        ...
    },
}

Вы можете увидеть текущий список движков баз данных, просмотрев каталог django / db / backends .

Использование внешнего механизма базы данных

Помимо официально поддерживаемых баз данных, существуют внешние по отношению к Django механизмы, которые позволяют использовать другие базы данных с Django:

Версии Django и функций ORM, поддерживаемые этими неофициальными движками, сильно различаются. Если у вас есть какие-либо вопросы относительно конкретных возможностей этих неофициальных движков или вопросы поддержки, вам следует обратиться по каналам помощи, предлагаемым каждым из этих внешних проектов.

Copyright ©2021 All rights reserved