Jak przenieść model pomiędzy dwoma aplikacjami Django (Django 1.7)
Więc około rok temu zacząłem projekt i jak wszyscy nowi programiści nie skupiałem się zbytnio na strukturze, jednak teraz jestem dalej razem z Django zaczęło się wydawać, że mój układ projektu głównie moje modele są okropne w strukturze.
Mam modele przechowywane głównie w jednej aplikacji i naprawdę większość z tych modeli powinny być w ich własnych indywidualnych aplikacji, próbowałem i rozwiązać to i przenieść je z południa jednak uważam, że to trudne i naprawdę trudne ze względu na klucze obce ect.
Jednak Ze Względu Na Django 1.7 i wbudowane wsparcie dla migracji, czy jest lepszy sposób, aby to zrobić teraz?
11 answers
Usuwam starą odpowiedź, ponieważ może to spowodować utratę danych. Jak wspomniał ozan , możemy utworzyć 2 migracje po jednej w każdej aplikacji.
Pierwsza migracja w celu usunięcia modelu z pierwszej aplikacji.
$ python manage.py makemigrations old_app --empty
Edytuj plik migracji, aby uwzględnić te operacje.
class Migration(migrations.Migration):
database_operations = [migrations.AlterModelTable('TheModel', 'newapp_themodel')]
state_operations = [migrations.DeleteModel('TheModel')]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=database_operations,
state_operations=state_operations)
]
Druga migracja, która zależy od pierwszej migracji i utworzyć nową tabelę w 2. aplikacji. Po przeniesieniu kodu modelu do drugiej aplikacji
$ python manage.py makemigrations new_app
I edytować plik migracji do czegoś takiego.
class Migration(migrations.Migration):
dependencies = [
('old_app', 'above_migration')
]
state_operations = [
migrations.CreateModel(
name='TheModel',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
],
options={
'db_table': 'newapp_themodel',
},
bases=(models.Model,),
)
]
operations = [
migrations.SeparateDatabaseAndState(state_operations=state_operations)
]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 16:05:51
Można to zrobić dość łatwo za pomocą migrations.SeparateDatabaseAndState
. Zasadniczo, używamy operacji bazy danych do zmiany nazwy tabeli jednocześnie z dwoma operacjami stanu, aby usunąć model z historii jednej aplikacji i utworzyć go w innej.
Usuń ze starej aplikacji
python manage.py makemigrations old_app --empty
W migracji:
class Migration(migrations.Migration):
dependencies = []
database_operations = [
migrations.AlterModelTable('TheModel', 'newapp_themodel')
]
state_operations = [
migrations.DeleteModel('TheModel')
]
operations = [
migrations.SeparateDatabaseAndState(
database_operations=database_operations,
state_operations=state_operations)
]
Dodaj do nowej aplikacji
Najpierw skopiuj model do nowej aplikacji model.py, wtedy:
python manage.py makemigrations new_app
Wygeneruje to migrację z naiwną operacją CreateModel
jako jedyną operacją. Wrap that w operacji SeparateDatabaseAndState
takiej, że nie próbujemy odtworzyć tabeli. Należy również uwzględnić wcześniejszą migrację jako zależność:
class Migration(migrations.Migration):
dependencies = [
('old_app', 'above_migration')
]
state_operations = [
migrations.CreateModel(
name='TheModel',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
],
options={
'db_table': 'newapp_themodel',
},
bases=(models.Model,),
)
]
operations = [
migrations.SeparateDatabaseAndState(state_operations=state_operations)
]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 18:30:12
Napotkałem ten sam problem. odpowiedź Ozana Bardzo mi pomogła, ale niestety nie wystarczyła. Rzeczywiście miałem kilka foreignkey linkujących do modelu, który chciałem przenieść. Po pewnym bólu głowy znalazłem rozwiązanie, więc postanowiłem go opublikować, aby rozwiązać czas ludzi.
Potrzebujesz jeszcze 2 kroków:
- zanim cokolwiek zrobisz, zmień wszystkie swoje
ForeignKey
linkowanie doTheModel
naIntegerfield
. Następnie uruchompython manage.py makemigrations
- Po wykonaniu kroków Ozana, Przelicz ponownie klucze obce: odłóż
ForeignKey(TheModel)
zamiastIntegerField()
. Następnie wykonaj migracje ponownie (python manage.py makemigrations
). Następnie można migrować i powinno działać (python manage.py migrate
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:27
Jak to zrobiłem (testowałem na Django= = 1.8, z postgresem, więc pewnie też 1.7)
Sytuacja
App1.YourModel
Ale chcesz, żeby to poszło do: app2.YourModel
- skopiuj YourModel (kod) z app1 do app2.
-
Dodaj to do app2.YourModel:
Class Meta: db_table = 'app1_yourmodel'
-
$ python manage.py makemigrations app2
-
Nowa migracja (np. 0009_auto_something.py) jest wykonany w app2 z migracją.CreateModel() polecenie, Przenieś to polecenie do początkowej migracji app2 (np. 0001_initial.py) (będzie tak jak zawsze). A teraz Usuń utworzoną migrację = 0009_auto_something.py
Tak jak ty, jak app2.YourModel zawsze tam był, teraz Usuń istnienie app1.YourModel z Twoich migracji. Znaczenie: skomentuj polecenia CreateModel i każdą korektę lub datamigrację, której użyłeś później.
-
I oczywiście każdy odniesienie do app1.YourModel musi zostać zmieniony na app2.YourModel poprzez swój projekt. Ponadto, nie zapomnij, że wszystkie możliwe klucze obce do app1.YourModel w migracjach musi zostać zmieniony na app2.YourModel
Teraz jeśli zrobisz $ python manage.py migracja, nic się nie zmieniło, także gdy robisz $ python manage.py makemigracje, nic nowego nie zostało wykryte.
-
Teraz koniec: usuń Meta klasy z app2.YourModel i do $ python manage.py makemigrations app2 & & python manage.py migrate app2 (jeśli przyjrzysz się tej migracji, zobaczysz coś takiego:)
migrations.AlterModelTable( name='yourmodel', table=None, ),
Table = None, oznacza, że pobiera domyślną nazwę tabeli, która w tym przypadku będzie app2_yourmodel.
- zrobione, z zapisanymi danymi.
P. s podczas migracji zobaczy, że content_type app1.yourmodel został usunięty i może zostać usunięty. Możesz się na to zgodzić, ale tylko jeśli tego nie użyjesz. Na wypadek, gdybyś mocno zależy od tego, aby FKs miał nienaruszony typ zawartości, NIE ODPOWIADAJ jeszcze tak lub nie, ale wejdź do db tym razem ręcznie i usuń aplikację contentype 2.yourmodel I zmienić nazwę aplikacji contenttype 1.yourmodel do app2.yourmodel, a następnie kontynuować odpowiadając nie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-11 15:06:51
Dostaję nerwowe migracje kodowania ręcznego (co jest wymagane przez Ozana odpowiedź), więc następujące kombinacje strategii Ozana I Michaela , aby zminimalizować ilość wymaganego kodowania ręcznego: {79]}
- przed przeniesieniem jakichkolwiek modeli upewnij się, że pracujesz z czystą linią bazową, uruchamiając
makemigrations
. - Przenieś kod dla modelu z
app1
naapp2
-
Zgodnie z zaleceniami @Michael, kierujemy nowy model do starej tabeli bazy danych za pomocą Meta
db_table
opcja na "nowy" model:class Meta: db_table = 'app1_yourmodel'
Run
makemigrations
. Spowoduje to wygenerowanieCreateModel
wapp2
iDeleteModel
wapp1
. Technicznie migracje te odnoszą się do tej samej tabeli i usuwają (łącznie z wszystkimi danymi) i ponownie tworzą tabelę.-
W rzeczywistości, nie chcemy (lub nie musimy) robić nic do stołu. Potrzebujemy tylko Django, aby uwierzyć, że zmiana została dokonana. @ Ozan ' s answer, the
state_operations
flag inSeparateDatabaseAndState
does this. Więc owijamy wszystkiemigrations
wpisy w obu plikach migracji zSeparateDatabaseAndState(state_operations=[...])
. Na przykład,operations = [ ... migrations.DeleteModel( name='YourModel', ), ... ]
Staje się
operations = [ migrations.SeparateDatabaseAndState(state_operations=[ ... migrations.DeleteModel( name='YourModel', ), ... ]) ]
-
EDIT: musisz również upewnić się, że nowa migracja "virtual"
CreateModel
zależy od migracji, która faktycznie utworzyła lub zmieniła oryginalną tabelę. Na przykład, jeśli nowe migracje toapp2.migrations.0004_auto_<date>
(dlaCreate
) iapp1.migrations.0007_auto_<date>
(dlaDelete
), najprostszą rzeczą do zrobienia jest:- Otwórz
app1.migrations.0007_auto_<date>
i skopiuj jej zależnośćapp1
(np.('app1', '0006...'),
). Jest to migracja" bezpośrednio przed " wapp1
i powinna zawierać zależności od całej rzeczywistej logiki budowania modelu. - Otwórz
app2.migrations.0004_auto_<date>
i dodaj skopiowaną zależność do listydependencies
.
- Otwórz
EDIT : Jeśli masz ForeignKey
relacje z Modelem, który poruszasz, powyższe może nie działać. Dzieje się tak dlatego, że:
- zależności nie są tworzone automatycznie dla zmian
ForeignKey
- Nie chcemy aby zawinąć
ForeignKey
zmiany wstate_operations
, musimy upewnić się, że są one oddzielone od operacji tabeli.
"minimalny" zestaw operacji różni się w zależności od sytuacji, ale następująca procedura powinna działać dla większości / wszystkich migracji ForeignKey
:
-
skopiuj model z
app1
naapp2
, Ustawdb_table
, ale nie zmieniaj żadnych referencji FK. - Uruchom
makemigrations
i zawiń wszystkie migracjeapp2
wstate_operations
(patrz wyżej)- jak wyżej, dodaj zależność w na
app2
CreateTable
do najnowszejapp1
migracji
- jak wyżej, dodaj zależność w na
- wskaż Wszystkie odniesienia FK do nowego modelu. Jeśli nie używasz referencji łańcuchowych, przenieś stary model na dół
models.py
(nie usuwaj go), aby nie konkurował z zaimportowaną klasą. -
Run
makemigrations
but DON ' t wrap anything instate_operations
(The FK changes should actually happen)- Dodaj zależność we wszystkich
ForeignKey
migracjach (tj.AlterField
) doCreateTable
migracji wapp2
(będziesz potrzebujesz tej listy do następnego kroku, więc śledź je). Na przykład: - Znajdź migrację, która zawiera
CreateModel
np.app2.migrations.0002_auto_<date>
i skopiuj nazwę tej migracji. -
Znajdź wszystkie migracje, które mają ForeignKey do tego modelu (np. wyszukując
app2.YourModel
, aby znaleźć migracje takie jak:class Migration(migrations.Migration): dependencies = [ ('otherapp', '0001_initial'), ] operations = [ migrations.AlterField( model_name='relatedmodel', name='fieldname', field=models.ForeignKey(... to='app2.YourModel'), ), ]
-
Dodaj
CreateModel
migrację jako zależność:class Migration(migrations.Migration): dependencies = [ ('otherapp', '0001_initial'), ('app2', '0002_auto_<date>'), ]
- Dodaj zależność we wszystkich
Usuń modele z
app1
- Run
makemigrations
and wrap theapp1
migracja wstate_operations
.- Dodaj zależność do wszystkich
ForeignKey
migracji (tj.AlterField
) z poprzedniego kroku (może zawierać migracje wapp1
iapp2
). - kiedy zbudowałem te migracje,
DeleteTable
już zależały odAlterField
, więc nie musiałem ręcznie tego wymuszać (np.Alter
przedDelete
).
- Dodaj zależność do wszystkich
W tym momencie Django jest gotowe. Nowy model wskazuje na starą tabelę i migracje Django przekonały go, że wszystko zostało odpowiednio przeniesione. Wielkie zastrzeżenie (od odpowiedzi @ Michael) jest takie, że nowy ContentType
jest tworzony dla nowego modelu. Jeśli połączysz (np. przez ForeignKey
) z typami zawartości, musisz utworzyć migrację, aby zaktualizować tabelę ContentType
.
Chciałem posprzątać po sobie (opcje Meta i nazwy tabel), więc zastosowałem następującą procedurę (od @Michael):
- Usuń
db_table
wpis Meta - Uruchom
makemigrations
ponownie, aby wygenerować bazę danych Zmień nazwę - Edytuj tę ostatnią migrację i upewnij się, że zależy ona od migracji
DeleteTable
. Nie wydaje się, że powinno być konieczne, ponieważDelete
powinno być czysto logiczne, ale napotkałem błędy (np.app1_yourmodel
nie istnieje), jeśli tego nie zrobię.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 18:42:05
Jest to testowane z grubsza, więc nie zapomnij wykonać kopii zapasowej DB!!!
Na przykład istnieją dwie aplikacje: src_app
i dst_app
, chcemy przenieść model MoveMe
z src_app
do dst_app
.
Tworzenie pustych migracji dla obu aplikacji:
python manage.py makemigrations --empty src_app
python manage.py makemigrations --empty dst_app
Załóżmy, że nowe migracje to XXX1_src_app_new
i XXX1_dst_app_new
, poprzednie top migracje to XXX0_src_app_old
i XXX0_dst_app_old
.
Dodaj operację, która zmienia nazwę tabeli dla modelu MoveMe
i zmienia nazwę jego app_label w ProjectState na XXX1_dst_app_new
. Nie zapomnij dodać zależność od XXX0_src_app_old
migracji. Wynik migracji XXX1_dst_app_new
to:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
# this operations is almost the same as RenameModel
# https://github.com/django/django/blob/1.7/django/db/migrations/operations/models.py#L104
class MoveModelFromOtherApp(migrations.operations.base.Operation):
def __init__(self, name, old_app_label):
self.name = name
self.old_app_label = old_app_label
def state_forwards(self, app_label, state):
# Get all of the related objects we need to repoint
apps = state.render(skip_cache=True)
model = apps.get_model(self.old_app_label, self.name)
related_objects = model._meta.get_all_related_objects()
related_m2m_objects = model._meta.get_all_related_many_to_many_objects()
# Rename the model
state.models[app_label, self.name.lower()] = state.models.pop(
(self.old_app_label, self.name.lower())
)
state.models[app_label, self.name.lower()].app_label = app_label
for model_state in state.models.values():
try:
i = model_state.bases.index("%s.%s" % (self.old_app_label, self.name.lower()))
model_state.bases = model_state.bases[:i] + ("%s.%s" % (app_label, self.name.lower()),) + model_state.bases[i+1:]
except ValueError:
pass
# Repoint the FKs and M2Ms pointing to us
for related_object in (related_objects + related_m2m_objects):
# Use the new related key for self referential related objects.
if related_object.model == model:
related_key = (app_label, self.name.lower())
else:
related_key = (
related_object.model._meta.app_label,
related_object.model._meta.object_name.lower(),
)
new_fields = []
for name, field in state.models[related_key].fields:
if name == related_object.field.name:
field = field.clone()
field.rel.to = "%s.%s" % (app_label, self.name)
new_fields.append((name, field))
state.models[related_key].fields = new_fields
def database_forwards(self, app_label, schema_editor, from_state, to_state):
old_apps = from_state.render()
new_apps = to_state.render()
old_model = old_apps.get_model(self.old_app_label, self.name)
new_model = new_apps.get_model(app_label, self.name)
if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
# Move the main table
schema_editor.alter_db_table(
new_model,
old_model._meta.db_table,
new_model._meta.db_table,
)
# Alter the fields pointing to us
related_objects = old_model._meta.get_all_related_objects()
related_m2m_objects = old_model._meta.get_all_related_many_to_many_objects()
for related_object in (related_objects + related_m2m_objects):
if related_object.model == old_model:
model = new_model
related_key = (app_label, self.name.lower())
else:
model = related_object.model
related_key = (
related_object.model._meta.app_label,
related_object.model._meta.object_name.lower(),
)
to_field = new_apps.get_model(
*related_key
)._meta.get_field_by_name(related_object.field.name)[0]
schema_editor.alter_field(
model,
related_object.field,
to_field,
)
def database_backwards(self, app_label, schema_editor, from_state, to_state):
self.old_app_label, app_label = app_label, self.old_app_label
self.database_forwards(app_label, schema_editor, from_state, to_state)
app_label, self.old_app_label = self.old_app_label, app_label
def describe(self):
return "Move %s from %s" % (self.name, self.old_app_label)
class Migration(migrations.Migration):
dependencies = [
('dst_app', 'XXX0_dst_app_old'),
('src_app', 'XXX0_src_app_old'),
]
operations = [
MoveModelFromOtherApp('MoveMe', 'src_app'),
]
Dodaj zależność od XXX1_dst_app_new
do XXX1_src_app_new
. {[8] } jest migracją no-op, która jest potrzebna, aby upewnić się, że przyszłe migracje src_app
będą wykonywane po XXX1_dst_app_new
.
Przesuń MoveMe
z src_app/models.py
na dst_app/models.py
. Następnie uruchom:
python manage.py migrate
To wszystko!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-12 19:09:43
Możesz wypróbować następujące (nieprzetestowane):
- przenieś model z
src_app
Nadest_app
- migrate
dest_app
; Upewnij się, że migracja schematu zależy od najnowszej migracjisrc_app
( https://docs.djangoproject.com/en/dev/topics/migrations/#migration-files ) - dodaj migrację danych do
dest_app
, która kopiuje wszystkie dane zsrc_app
- migrate
src_app
; upewnij się, że migracja schematu zależy od najnowszej (danych) migracjidest_app
-- czyli: migracji kroku 3
Zauważ, że będziesz kopiować całą tabelę, zamiast przenosić, ale w ten sposób obie aplikacje nie muszą dotykać tabeli, która należy do drugiej aplikacji, co moim zdaniem jest ważniejsze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-13 13:18:41
Powiedzmy, że przenosisz Model TheModel z app_a do app_b.
Alternatywnym rozwiązaniem jest Ręczna zmiana istniejących migracji. Chodzi o to, że za każdym razem, gdy widzisz operację zmieniającą model w migracjach app_a, kopiujesz tę operację do końca początkowej migracji app_b. I za każdym razem, gdy widzisz odniesienie 'app_a. TheModel' w migracjach app_a, zmieniasz je na 'app_b. TheModel'.
Zrobiłem to dla istniejącego projektu, w którym chciałem wyodrębnić pewną model do aplikacji wielokrotnego użytku. Procedura przebiegła sprawnie. Myślę, że byłoby znacznie trudniej, gdyby były odniesienia od app_b do app_a. również miałem ręcznie zdefiniowaną Meta.db_table dla mojego modelu, który mógłby pomóc.
Zwłaszcza, że skończysz ze zmienioną historią migracji. Nie ma to znaczenia, nawet jeśli masz bazę danych z zastosowanymi oryginalnymi migracjami. Jeśli zarówno oryginalne, jak i przepisane migracje kończą się tym samym schematem bazy danych, to takie przepisanie powinno być OK.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-13 07:11:10
- Zmień nazwy starych modeli na'model_name_old'
- makemigracje
- twórz nowe modele o nazwie 'model_name_new' z identycznymi relacjami na powiązanych modelach (np. model użytkownika ma teraz użytkownika.blog_old i użytkownik.blog_new)
- makemigracje
- napisz niestandardową migrację, która migruje wszystkie dane do nowych tabel modeli
- przetestuj te migracje porównując kopie zapasowe z nowymi kopiami db przed i po uruchomieniu migracje
- gdy wszystko jest zadowalające, usuń stare modele
- makemigracje
- Zmień nowe modele na poprawną nazwę 'model_name_new' - > 'model_name'
- przetestuj całą masę migracji na serwerze testowym
- Wyłącz swoją witrynę produkcyjną na kilka minut, aby uruchomić wszystkie migracje bez ingerencji użytkowników
Zrób to indywidualnie dla każdego modelu, który musi zostać przeniesiony. Nie sugerowałbym robienia tego, co mówi druga odpowiedź przez zmiana na liczby całkowite i powrót do kluczy obcych Istnieje szansa, że nowe klucze obce będą różne, a wiersze mogą mieć różne identyfikatory po migracji i nie chciałem ryzykować niedopasowania identyfikatorów podczas przełączania z powrotem na klucze obce.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-04 05:25:20
Inną hacky alternatywą, jeśli dane nie są duże lub zbyt skomplikowane, ale nadal ważne do utrzymania, jest:
- Pobierz oprawy danych za pomocą manage.py dumpdata
- przystąpić do modelowania zmian i migracji prawidłowo, bez powiązania zmian
- Global zastąp urządzenia ze starego modelu i nazw aplikacji na nowe
- załaduj dane za pomocą manage.py loaddata
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-20 06:45:07
Skopiowane z mojej odpowiedzi na https://stackoverflow.com/a/47392970/8971048
W przypadku, gdy musisz przenieść model i nie masz już dostępu do aplikacji( lub nie chcesz dostępu), możesz utworzyć nową operację i rozważyć utworzenie nowego modelu tylko wtedy, gdy migrowany model nie istnieje.
W tym przykładzie przekazuję 'MyModel' z old_app do myapp.
class MigrateOrCreateTable(migrations.CreateModel):
def __init__(self, source_table, dst_table, *args, **kwargs):
super(MigrateOrCreateTable, self).__init__(*args, **kwargs)
self.source_table = source_table
self.dst_table = dst_table
def database_forwards(self, app_label, schema_editor, from_state, to_state):
table_exists = self.source_table in schema_editor.connection.introspection.table_names()
if table_exists:
with schema_editor.connection.cursor() as cursor:
cursor.execute("RENAME TABLE {} TO {};".format(self.source_table, self.dst_table))
else:
return super(MigrateOrCreateTable, self).database_forwards(app_label, schema_editor, from_state, to_state)
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_some_migration'),
]
operations = [
MigrateOrCreateTable(
source_table='old_app_mymodel',
dst_table='myapp_mymodel',
name='MyModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=18))
],
),
]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 13:23:03