mirror of
https://github.com/carrotquest/django-clickhouse.git
synced 2024-11-29 04:23:45 +03:00
commit
007ff70d5e
84
.travis.yml
Normal file
84
.travis.yml
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
dist: xenial
|
||||||
|
sudo: required
|
||||||
|
language: python
|
||||||
|
cache:
|
||||||
|
pip: true
|
||||||
|
apt: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
- postgresql
|
||||||
|
- redis-server
|
||||||
|
addons:
|
||||||
|
postgresql: "11"
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- sourceline: "deb http://repo.yandex.ru/clickhouse/deb/stable/ main/"
|
||||||
|
- sourceline: "deb https://packages.erlang-solutions.com/ubuntu xenial contrib"
|
||||||
|
key_url: "https://packages.erlang-solutions.com/ubuntu/erlang_solutions.asc"
|
||||||
|
- sourceline: "deb https://dl.bintray.com/rabbitmq/debian xenial main"
|
||||||
|
key_url: "https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc"
|
||||||
|
packages:
|
||||||
|
- dirmngr
|
||||||
|
- apt-transport-https
|
||||||
|
- postgresql-contrib-9.6
|
||||||
|
- postgresql-10
|
||||||
|
- postgresql-contrib-10
|
||||||
|
- postgresql-client-10
|
||||||
|
- postgresql-11
|
||||||
|
- postgresql-contrib-11
|
||||||
|
- postgresql-client-11
|
||||||
|
- unzip
|
||||||
|
- rabbitmq-server
|
||||||
|
|
||||||
|
python:
|
||||||
|
- 3.6
|
||||||
|
- 3.7
|
||||||
|
|
||||||
|
env:
|
||||||
|
- PG=9.6 DJANGO=2.1
|
||||||
|
- PG=10 DJANGO=2.1
|
||||||
|
- PG=11 DJANGO=2.1
|
||||||
|
- PG=9.6 DJANGO=2.2
|
||||||
|
- PG=10 DJANGO=2.2
|
||||||
|
- PG=11 DJANGO=2.2
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
# Use default PostgreSQL 11 port
|
||||||
|
- sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/11/main/postgresql.conf
|
||||||
|
- sudo cp /etc/postgresql/{10,11}/main/pg_hba.conf
|
||||||
|
|
||||||
|
# Start PostgreSQL version we need
|
||||||
|
- sudo systemctl stop postgresql && sudo systemctl start postgresql@$PG-main
|
||||||
|
|
||||||
|
# ClickHouse sources
|
||||||
|
- sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E0C56BD4
|
||||||
|
- sudo apt-get update
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
# Install ClickHouse
|
||||||
|
- sudo apt-get install clickhouse-client clickhouse-server clickhouse-common-static
|
||||||
|
- sudo service clickhouse-server restart
|
||||||
|
|
||||||
|
- pip install -r requirements.txt
|
||||||
|
- pip install -q Django==$DJANGO.*
|
||||||
|
- pip install redis
|
||||||
|
- python setup.py -q install
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
# Output software versions
|
||||||
|
- erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell
|
||||||
|
- rabbitmqctl status | grep "RabbitMQ"
|
||||||
|
- clickhouse-client --query "SELECT version();"
|
||||||
|
- psql -tc 'SHOW server_version' -U postgres
|
||||||
|
|
||||||
|
- psql -tc 'SHOW server_version' -U postgres
|
||||||
|
- psql -c 'CREATE ROLE test;' -U postgres
|
||||||
|
- psql -c 'ALTER ROLE test WITH SUPERUSER;' -U postgres
|
||||||
|
- psql -c 'ALTER ROLE test WITH LOGIN;' -U postgres
|
||||||
|
- psql -c "ALTER ROLE test PASSWORD 'test';" -U postgres
|
||||||
|
- psql -c 'CREATE DATABASE test OWNER test;' -U postgres
|
||||||
|
- psql -c 'CREATE DATABASE test2 OWNER test;' -U postgres
|
||||||
|
|
||||||
|
script:
|
||||||
|
python runtests.py
|
|
@ -10,11 +10,9 @@ def namedtuple(*args, **kwargs):
|
||||||
:return: namedtuple class
|
:return: namedtuple class
|
||||||
"""
|
"""
|
||||||
if sys.version_info < (3, 7):
|
if sys.version_info < (3, 7):
|
||||||
defaults = kwargs.pop('defaults', {})
|
defaults = kwargs.pop('defaults', ())
|
||||||
TupleClass = basenamedtuple(*args, **kwargs)
|
TupleClass = basenamedtuple(*args, **kwargs)
|
||||||
TupleClass.__new__.__defaults__ = (None,) * len(TupleClass._fields)
|
TupleClass.__new__.__defaults__ = (None,) * (len(TupleClass._fields) - len(defaults)) + tuple(defaults)
|
||||||
prototype = TupleClass(*defaults)
|
|
||||||
TupleClass.__new__.__defaults__ = tuple(prototype)
|
|
||||||
return TupleClass
|
return TupleClass
|
||||||
else:
|
else:
|
||||||
return basenamedtuple(*args, **kwargs)
|
return basenamedtuple(*args, **kwargs)
|
||||||
|
|
|
@ -119,12 +119,11 @@ class MigrationHistory(ClickHouseModel):
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
# Ensure that table for migration storing is created
|
# Ensure that table for migration storing is created
|
||||||
for db_alias in cls.migrate_non_replicated_db_aliases:
|
for db_name in cls.migrate_non_replicated_db_aliases:
|
||||||
connections[db_alias].create_table(cls)
|
connections[db_name].create_table(cls)
|
||||||
|
|
||||||
cls.objects.bulk_create([
|
cls.objects.create(db_alias=db_alias, package_name=migrations_package, module_name=name,
|
||||||
cls(db_alias=db_alias, package_name=migrations_package, module_name=name, applied=datetime.date.today())
|
applied=datetime.date.today())
|
||||||
])
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_applied_migrations(cls, db_alias, migrations_package): # type: (str, str) -> Set[str]
|
def get_applied_migrations(cls, db_alias, migrations_package): # type: (str, str) -> Set[str]
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from time import gmtime, localtime
|
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
@ -12,9 +10,13 @@ from django_clickhouse.utils import get_tz_offset, format_datetime, lazy_class_i
|
||||||
SingletonMeta
|
SingletonMeta
|
||||||
|
|
||||||
|
|
||||||
class GetTZOffsetTest(TestCase):
|
def local_dt_str(dt) -> str:
|
||||||
def test_func(self):
|
"""
|
||||||
self.assertEqual(300, get_tz_offset())
|
Returns string representation of an aware datetime object, localized by adding system_tz_offset()
|
||||||
|
:param dt: Datetime to change
|
||||||
|
:return: Formatted string
|
||||||
|
"""
|
||||||
|
return (dt + datetime.timedelta(minutes=get_tz_offset())).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
|
||||||
class FormatDateTimeTest(TestCase):
|
class FormatDateTimeTest(TestCase):
|
||||||
|
@ -25,32 +27,33 @@ class FormatDateTimeTest(TestCase):
|
||||||
:param dt: Объект datetime.datetime
|
:param dt: Объект datetime.datetime
|
||||||
:return: Строковый ожидаемый результат
|
:return: Строковый ожидаемый результат
|
||||||
"""
|
"""
|
||||||
moscow_minute_offset = dt.utcoffset().total_seconds() / 60
|
minute_offset = dt.utcoffset().total_seconds() / 60
|
||||||
zone_h, zone_m = abs(int(moscow_minute_offset / 60)), int(moscow_minute_offset % 60)
|
zone_h, zone_m = abs(int(minute_offset / 60)), int(minute_offset % 60)
|
||||||
|
|
||||||
# +5 за счет времени тестового сервера ClickHouse
|
return local_dt_str(dt - datetime.timedelta(hours=zone_h, minutes=zone_m))
|
||||||
return (dt - datetime.timedelta(hours=zone_h - 5, minutes=zone_m)).strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
|
|
||||||
def test_conversion(self):
|
def test_conversion(self):
|
||||||
dt = datetime.datetime(2017, 1, 2, 3, 4, 5)
|
dt = datetime.datetime(2017, 1, 2, 3, 4, 5)
|
||||||
self.assertEqual(format_datetime(dt), '2017-01-02 08:04:05')
|
self.assertEqual(format_datetime(dt), local_dt_str(dt))
|
||||||
dt = datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=pytz.utc)
|
dt = datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=pytz.utc)
|
||||||
self.assertEqual(format_datetime(dt), '2017-01-02 08:04:05')
|
self.assertEqual(format_datetime(dt), local_dt_str(dt))
|
||||||
dt = datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=pytz.timezone('Europe/Moscow'))
|
dt = datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=pytz.timezone('Europe/Moscow'))
|
||||||
self.assertEqual(format_datetime(dt), self._get_zone_time(dt))
|
self.assertEqual(format_datetime(dt), self._get_zone_time(dt))
|
||||||
dt = datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=pytz.timezone('Europe/Moscow'))
|
dt = datetime.datetime(2017, 1, 2, 3, 4, 5, tzinfo=pytz.timezone('Europe/Moscow'))
|
||||||
offset = int(pytz.timezone('Europe/Moscow').utcoffset(dt).total_seconds() / 60)
|
offset = int(pytz.timezone('Europe/Moscow').utcoffset(dt).total_seconds() / 60)
|
||||||
self.assertEqual(format_datetime(dt, timezone_offset=offset), '2017-01-02 03:04:05')
|
self.assertEqual(format_datetime(dt, timezone_offset=offset),
|
||||||
|
local_dt_str(datetime.datetime(2017, 1, 2, 3, 4, 5) - datetime.timedelta(minutes=offset*2)))
|
||||||
|
|
||||||
def test_date_conversion(self):
|
def test_date_conversion(self):
|
||||||
dt = datetime.date(2017, 1, 2)
|
dt = datetime.date(2017, 1, 2)
|
||||||
self.assertEqual(format_datetime(dt), '2017-01-02 05:00:00')
|
self.assertEqual(format_datetime(dt), local_dt_str(datetime.datetime(2017, 1, 2, 0, 0, 0)))
|
||||||
dt = datetime.date(2017, 1, 2)
|
dt = datetime.date(2017, 1, 2)
|
||||||
self.assertEqual(format_datetime(dt, day_end=True), '2017-01-03 04:59:59')
|
self.assertEqual(format_datetime(dt, day_end=True), local_dt_str(datetime.datetime(2017, 1, 2, 23, 59, 59)))
|
||||||
dt = datetime.date(2017, 1, 2)
|
dt = datetime.date(2017, 1, 2)
|
||||||
self.assertEqual(format_datetime(dt, day_end=True, timezone_offset=60), '2017-01-03 03:59:59')
|
self.assertEqual(format_datetime(dt, day_end=True, timezone_offset=60),
|
||||||
|
local_dt_str(datetime.datetime(2017, 1, 2, 22, 59, 59)))
|
||||||
dt = datetime.date(2017, 1, 2)
|
dt = datetime.date(2017, 1, 2)
|
||||||
self.assertEqual(format_datetime(dt, timezone_offset=60), '2017-01-02 04:00:00')
|
self.assertEqual(format_datetime(dt, timezone_offset=60), local_dt_str(datetime.datetime(2017, 1, 1, 23, 0, 0)))
|
||||||
|
|
||||||
|
|
||||||
class TestLazyClassImport(TestCase):
|
class TestLazyClassImport(TestCase):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user