5

MySQL 5.6.4 i rozszerza się wsparcie ułamków sekund wartości czasu, data i godzina, i znacznik czasu z góry mikrosekund (6 cyfr) Dokładność: http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.htmlJak utworzyć niestandardowe pole Django do przechowywania DATETIME MYSQL (6) i włączyć ułamkowe sekundy (milisekundy lub mikrosekundy) w Django/MySQL?

Django 1,5 się obsługuje sekund frakcjonowaną imputformat: https://docs.djangoproject.com/en/1.5/ref/settings/#datetime-input-formats

Ale pole DATETIME (6) nie jest jeszcze zaimplementowane w Django. https://code.djangoproject.com/ticket/19716

Postanowiłem napisać niestandardowy obiekt DateTimeFractionField. Jest to standardowa funkcja DateTimeField z parametrem db_type DATETIME ([1-6]). "precicion" to ustawienie milisekund, mikrosekund lub jakiejkolwiek innej prefikcji frakcji.

class DateTimeFractionField(models.DateTimeField): 
    description = "Datetimefield with fraction second." 

    def __init__(self, precision, *args, **kwargs): 
     self.precision = precision 
     super(DateTimeFractionField, self).__init__(*args, **kwargs) 

    def db_type(self, connection): 
     return 'DATETIME(%s)' % self.precision 


class MyModel(models.Model): 
    dt_micros = DateTimeFractionField(6) 
    dt_millis = DateTimeFractionField(3) 
    dt = models.DateTimeField() 

    def __unicode__(self): 
     return "%s - %s" %(self.dt_micros, self.dt_millis) 

MySQL backend jest odpowiedzialny za zastąpienie milisekund 0. Dokumentacja Django sugeruje, aby napisać własny backend. https://docs.djangoproject.com/en/1.5/ref/settings/#engine

I hacked:

$ cd /path/to/site-packages/django/db/backends/ 
$ cp -r mysql mysql564 

i modyfikowane mysql564/base.py:

Linia 42:45

from django.db.backends.mysql564.client import DatabaseClient 
from django.db.backends.mysql564.creation import DatabaseCreation 
from django.db.backends.mysql564.introspection import DatabaseIntrospection 
from django.db.backends.mysql564.validation import DatabaseValidation 

Linia 167

supports_microsecond_precision = True 

Linia 214

compiler_module = "django.db.backends.mysql564.compiler" 

Linia 357

return six.text_type(value) #value.replace(microsecond=0) 

Linia 368

return six.text_type(value) #value.replace(microsecond=0) 

Linia 373

return [first, second] #return [first.replace(microsecond=0), second.replace(microsecond=0)] 

potem aktywowany mój nowy backend w settings.py:

'ENGINE': 'django.db.backends.mysql564', 

Po dodaniu i zapisaniu mojego modelu w panelu administracyjnym, wartości zostają zapisane do de db! :)

Sequel Pro

Ale oni nie są zwracane (Brak - Brak i puste pola formularza). :(

Django admin

Co ja tu brakuje?

  1. Dlaczego wartości DateTimeFractionField nie wrócił?
  2. Czy istnieje lepsza (prostszy) sposób wdrożenia DateTimeField że poparcie frakcji?

Wiem, że istnieją inne frakcje pomocnicze db.Ale lubię korzystać z MySQL i uzyskać bilet nieco bliżej do naprawienia.

UPDATE:

To nie (tylko) formy, coraz obiekt DateTime z de db zawiedzie.

In [1]: from spacetime.models import MyModel 

In [2]: from django.shortcuts import get_object_or_404 

In [3]: get_object_or_404(MyModel, pk=1).dt 
Out[3]: datetime.datetime(2013, 7, 25, 0, 22, 23) 

In [4]: get_object_or_404(MyModel, pk=1).dt_millis 

In [5]: get_object_or_404(MyModel, pk=1).dt_millis.__class__ 
Out[5]: NoneType #This should be datetime.datetime 
+0

Może to tylko ja, ale to trochę mylące, aby zobaczyć, co jesteś ac zapytać/próbować zrobić. – jdero

+0

Próbuję utworzyć obiekt DateTimeField obsługujący ułamkowe sekundy. Moja własna DateTimeField to DateTimeFractionField. Z powodzeniem zapisuje obiekty datetime z ułamkami w bazie danych, ale pobieranie wartości z db do Django nie działa. Ogólnym celem jest uzyskanie działającego pola DateTimeFractionField. Pytanie w tej chwili: Dlaczego nie są zwracane wartości DateTimeFractionField? – allcaps

+0

Django nie obsługuje go po wyjęciu z pudełka, jak rozumiem, ponieważ SQL nie ma specyfikacji. Możesz użyć CharField lub napisać własne pole, które używa kodu specyficznego dla bazy danych. – stormlifter

Odpowiedz

1

Próbowałem to z powodzeniem, ale moje podejście jest zupełnie inny: podzielić info w DateTimeField (UTC) i IntegerField (mikrosekundy = USA):

from datetime     import datetime, timedelta 
import pytz 

class MyModel (models.Model): 
    # My model stuff and other fields here 
    _UTC = models.DateTimeField() 
    _uS = models.IntegerField() 

a następnie i ustawić właściwość w klasie, aby powrócić UTC z mikrosekund oraz informacją strefy świadomy (bo moja baza danych nie obsługuje zoneInfo)

@property 
    def UTC (self): 
     utc = self._UTC 
     us = self._uS 
     # add microseconds 
     utc += timedelta(microseconds=us) 
     return utc.replace(tzinfo=pytz.utc) 
    @UTC.setter 
    def UTC (self,utc): 
     self._UTC = utc-timedelta(microseconds=utc.microsecond) # without microseconds 
     self._uS = utc.microsecond 
+0

Nice. Spróbuję tego. Django 1.8 będzie obsługiwać ułamki: https://docs.djangoproject.com/en/dev/releases/1.8/#database-backends – allcaps

+0

Należy pamiętać, że pole @property nie będzie działało dla filtrowania zapytań (MyModel.objects. filter (UTC ...) W tym celu konieczne jest filtrowanie przez _UTC i/lub _uS oddzielnie – Anr

Powiązane problemy