Лучший способ сохранить старые даты в SQL Server

Как описано в документации django ForeignKey , django просто эмулирует это поведение, а не откладывает его в базу данных.

Django эмулирует поведение ограничения SQL ON DELETE CASCADE, а также удаляет объект, содержащий ForeignKey.

blockquote>

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

Как еще можно заставить мой файл models.py вывести ограничение каскадного удаления внешнего ключа?

blockquote>

Вы не можете, поскольку в настоящее время django не поддерживает эту функцию. Однако есть билет, обсуждающий его добавление: https://code.djangoproject.com/ticket/21961


Изменить для дальнейшего разъяснения о том, как применить это в базе данных- level

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

Чтобы отказаться от операций по созданию или удалению таблицы базы данных, вы можете установить Options.managed в False в классе Meta из ArticleStat. Это, однако, также означает, что вы теперь несете ответственность за ручную миграцию, например, написать оператор CREATE TABLE для определения таблицы, включающей ограничение внешнего ключа (которое теперь у вас есть полный контроль). Еще одно соображение, которое следует принять во внимание, заключается в том, что вы должны указать django больше ничего не делать при удалении объекта Article, на который есть ссылка (так как ваша база данных теперь отвечает за это). Это можно обеспечить, установив on_delete в models.DO_NOTHING .

Теперь ваши ArticleStat будут выглядеть следующим образом:

class ArticleStat(models.Model):
    article = models.ForeignKey(Article, on_delete=models.DO_NOTHING)

    class Meta:
        managed = False

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

  • Отказ означает также отказ от сигналов Django. В частности, pre_delete и post_delete больше не будут запускаться для каскадных объектов.

  • Как упомянуто в описании билетов , смешивание базы данных и django-каскадирование не будут хорошо сочетаться.

    Если модель A ссылается на модель B с использованием CASCADE_DB, а модель B ссылается на модель C с использованием обычного CASCADE, удаление A не будет каскадно полностью вплоть до C.

    blockquote>

При этом я не смог найти какое-либо определенное доказательство того, почему django ведет себя так, как в настоящее время. [Тысяча сто тридцать одна]

10
задан bdukes 9 October 2009 в 22:11
поделиться

7 ответов

date тип определенно, что Вы хотите использовать. Это - диапазон, "1 января, 1 нашей эры в течение 31 декабря, 9999 нашей эры". Это также просто хранит информацию даты без части времени.

Вы, возможно, с помощью SSMS 2005, а не 2008, или подключенный к экземпляру 2005 года? Тот тип был представлен в SQL Server 2008. Если бы у Вас есть способность использовать базу данных 2008 года, я думал бы что она бесспорно способ пойти.

15
ответ дан 3 December 2019 в 15:53
поделиться

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

Это должно быть довольно эффективно с точки зрения выбора и сортировки.

4
ответ дан 3 December 2019 в 15:53
поделиться

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

Так, например:

CREATE TABLE myOldDates (
  year INT,
  month INT,
  day INT,
  -- otherstuff ...
)

Затем запросы были бы все похожи:

-- get records between 5/15/1752 and 3/19/1754
SELECT * FROM myOldDates
  WHERE 
    (year = 1752 AND ((month = 5 and day >= 15) or month > 5) OR year > 1752)
    AND (year = 1754 AND ((month = 3 and day <= 19) or month < 3) OR year < 1754)

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

4
ответ дан 3 December 2019 в 15:53
поделиться

YYYYMMDD = 8 байтов. Вы могли сократить его к 4 байтам с SMALLINT и TINYINT использование 3 столбцов.

1
ответ дан 3 December 2019 в 15:53
поделиться

Одна проблема с хранением дат в формате YYYYMMDD состоит в том, что Вы могли закончить с датами, которые не существуют (например, 16000231 - Febuary 31 не существует). Необходимо было бы сделать некоторую сторону клиента проверки, прежде, чем ввести его в дб.

То же, конечно, верно для хранения даты в году, месяце и дневных целых числах, как предложено Ian Varley. Но в стороне от этого я люблю его ответ и просто желаю, чтобы я думал бы о нем ;-)

1
ответ дан 3 December 2019 в 15:53
поделиться

Используя ints, как предложено CodeMonkey1 походит на хорошую идею и поможет сделать "математику даты" (например, некоторая дата + XX дней).

Запишите некоторый UDFs (также, как рекомендуется CodeMonkey1) для преобразования интервала-> YYYYMMDD-> интервал, и у Вас будет гибкость, которую Ian Varley упоминает в своем ответе.

1
ответ дан 3 December 2019 в 15:53
поделиться

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

1
ответ дан 3 December 2019 в 15:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: