problem timestamp dengan oracle

1 parent 69eea7d7
...@@ -311,7 +311,8 @@ def get_config(settings): ...@@ -311,7 +311,8 @@ def get_config(settings):
def init_db(settings): def init_db(settings):
engine = engine_from_config( engine = engine_from_config(
settings, 'sqlalchemy.', client_encoding='utf8', settings, 'sqlalchemy.',
# client_encoding='utf8',
max_identifier_length=30) # , convert_unicode=True max_identifier_length=30) # , convert_unicode=True
...@@ -328,6 +329,13 @@ def init_db(settings): ...@@ -328,6 +329,13 @@ def init_db(settings):
def datetime_output_handler(cursor, name, default_type, size, precision, scale):
"""Intercepts Oracle TSTZ data types and returns them with tzinfo intact."""
# DB_TYPE_TIMESTAMP_TZ handles Oracle's 'TIMESTAMP WITH TIME ZONE'
import oracledb
if default_type == oracledb.DB_TYPE_TIMESTAMP_TZ:
return cursor.var(oracledb.DB_TYPE_TIMESTAMP_TZ, arraysize=cursor.arraysize, outconverter=lambda v: v)
def main(global_config, **settings): def main(global_config, **settings):
""" This function returns a Pyramid WSGI application. """ This function returns a Pyramid WSGI application.
""" """
...@@ -336,6 +344,21 @@ def main(global_config, **settings): ...@@ -336,6 +344,21 @@ def main(global_config, **settings):
if not settings.get('localization', ''): if not settings.get('localization', ''):
settings['localization'] = 'id_ID.UTF-8' settings['localization'] = 'id_ID.UTF-8'
if settings.get("lib_dir"):
sqlalchemy_url = settings.get("sqlalchemy.url")
if sqlalchemy_url and sqlalchemy_url.find("oracledb") > -1:
try:
import oracledb
oracledb.init_oracle_client(lib_dir=settings.get("lib_dir"))
# Apply the global configuration handler to your connection pool
oracledb.defaults.outputtypehandler = datetime_output_handler
_logging.debug("oracledb initialized")
except:
pass
locale.setlocale(locale.LC_ALL, settings['localization']) locale.setlocale(locale.LC_ALL, settings['localization'])
if 'timezone' not in settings: if 'timezone' not in settings:
settings['timezone'] = DefaultTimeZone settings['timezone'] = DefaultTimeZone
......
...@@ -174,8 +174,12 @@ def upgrade(): ...@@ -174,8 +174,12 @@ def upgrade():
op.create_table('users', op.create_table('users',
sa.Column('last_login_date', sa.DateTime(timezone=True), nullable=True), sa.Column('last_login_date', sa.DateTime(timezone=True), nullable=True),
sa.Column('registered_date', sa.DateTime(timezone=True), nullable=False), sa.Column('registered_date', sa.DateTime(timezone=True), nullable=False),
sa.Column('security_code_date', sa.DateTime(timezone=True), # sa.Column('security_code_date', sa.DateTime(timezone=True),
# nullable=True), # server_default='2000-01-01 01:01+7',
# from sqlalchemy.types import TIMESTAMP
sa.Column('security_code_date', sa.types.TIMESTAMP(timezone=True),
nullable=True), # server_default='2000-01-01 01:01+7', nullable=True), # server_default='2000-01-01 01:01+7',
sa.Column('api_key', sa.String(length=256), nullable=True), sa.Column('api_key', sa.String(length=256), nullable=True),
sa.Column('partner_id', sa.Integer(), nullable=True), sa.Column('partner_id', sa.Integer(), nullable=True),
sa.Column('company_id', sa.Integer(), nullable=True), sa.Column('company_id', sa.Integer(), nullable=True),
......
from sqlalchemy import (Column, Integer, ForeignKey, String, SmallInteger, text) from sqlalchemy import (Column, Integer, ForeignKey,
String, SmallInteger, text)
from sqlalchemy.orm import (relationship, backref, declared_attr) from sqlalchemy.orm import (relationship, backref, declared_attr)
from ..models import DBSession, Base from ..models import DBSession, Base
from ..models import (NamaModel, TABLE_ARGS) from ..models import (NamaModel, TABLE_ARGS)
...@@ -55,15 +56,37 @@ class _Departemen(NamaModel): ...@@ -55,15 +56,37 @@ class _Departemen(NamaModel):
parent_id = kwargs.get('id', None) parent_id = kwargs.get('id', None)
str_where = parent_id and " parent_id={} ".format( str_where = parent_id and " parent_id={} ".format(
parent_id) or " parent_id IS NULL" parent_id) or " parent_id IS NULL"
eng = cls.db_session.get_bind()
if eng.dialect.name.lower() == "oracle":
sql = """ sql = """
WITH RECURSIVE dep_tree AS ( SELECT
--LPAD(' ', (LEVEL - 1) * 2) || nama AS hierarchy,
SYS_CONNECT_BY_PATH(nama, '/') AS hierarchy,
id,
kode,
nama,
parent_id,
status,
(LEVEL - 1) AS lvl,
SYS_CONNECT_BY_PATH(id, ',') AS path
FROM
departemen
START WITH
parent_id IS NULL
CONNECT BY
PRIOR id = parent_id
ORDER SIBLINGS BY
id"""
else:
sql = """
WITH RECURSIVE dep_tree AS (
SELECT SELECT
id, id,
kode, kode,
nama, nama,
parent_id, parent_id,
status, status,
0 AS level, 0 AS lvl,
ARRAY[id] AS path ARRAY[id] AS path
FROM FROM
public.departemen public.departemen
...@@ -84,9 +107,9 @@ class _Departemen(NamaModel): ...@@ -84,9 +107,9 @@ class _Departemen(NamaModel):
JOIN JOIN
dep_tree ct ON c.parent_id = ct.id dep_tree ct ON c.parent_id = ct.id
) )
SELECT SELECT
REPEAT(' ', level) || nama AS hierarchy, -- Indent names based on level REPEAT(' ', lvl) || nama AS hierarchy, -- Indent names based on level
id, id,
kode, kode,
nama, nama,
...@@ -94,18 +117,17 @@ class _Departemen(NamaModel): ...@@ -94,18 +117,17 @@ class _Departemen(NamaModel):
status, status,
level, level,
path path
FROM FROM
dep_tree dep_tree
""".format(str_where=str_where) """.format(str_where=str_where)
if search: if search:
sql = f"{sql} WHERE nama ILIKE '%{search}%' " sql = f"{sql} WHERE nama ILIKE '%{search}%' "
sql=sql+"""ORDER BY path;""" sql = sql+"""ORDER BY path;"""
return cls.db_session.execute(text(sql)).fetchall() return cls.db_session.execute(text(sql)).fetchall()
class Departemen(_Departemen, Base): class Departemen(_Departemen, Base):
db_session = DBSession db_session = DBSession
...@@ -93,19 +93,20 @@ class _UserResourcePermission(UserResourcePermissionMixin): ...@@ -93,19 +93,20 @@ class _UserResourcePermission(UserResourcePermissionMixin):
class UserResourcePermission(_UserResourcePermission, Base): class UserResourcePermission(_UserResourcePermission, Base):
pass pass
from sqlalchemy import TIMESTAMP
class _User(UserMixin, BaseModel): class _User(UserMixin, BaseModel):
db_session = DBSession db_session = DBSession
last_login_date = Column(DateTime(timezone=True), nullable=True) last_login_date = Column(DateTime(timezone=True), nullable=True)
registered_date = Column(DateTime(timezone=True), registered_date = Column(DateTime(timezone=True),
nullable=False, nullable=False,
default=datetime.utcnow) default=datetime.utcnow)
security_code_date = Column(DateTime(timezone=True), # security_code_date = Column(DateTime(timezone=True),
default=datetime(2000, 1, 1, # default=datetime(2000, 1, 1,
tzinfo=pytz.timezone( # tzinfo=pytz.timezone(
'Asia/Jakarta')), # 'Asia/Jakarta')),
server_default="2000-01-01 01:01+7", # server_default="2000-01-01 01:01+7",
) # )
security_code_date = Column(TIMESTAMP(timezone=True))
api_key = Column(String(256)) api_key = Column(String(256))
partner_id = Column(Integer) # , ForeignKey(Partner.id)) partner_id = Column(Integer) # , ForeignKey(Partner.id))
company_id = Column(Integer) # , ForeignKey(Partner.id)) company_id = Column(Integer) # , ForeignKey(Partner.id))
......
...@@ -179,8 +179,8 @@ class Views(BaseView): ...@@ -179,8 +179,8 @@ class Views(BaseView):
url_dict = request.matchdict url_dict = request.matchdict
if url_dict['act'] == 'grid': if url_dict['act'] == 'grid':
query = Departemen.cte_get() query = Departemen.cte_get()
data = [{"id": d.id, "kode": d.kode, "nama": d.nama, "status": d.status, data = [{"id": d.id, "kode": d.kode, "nama": d.hierarchy[1:], "status": d.status,
"level_id":d.level, "parent_id": d.parent_id} for d in query] "level_id": d.lvl, "parent_id": d.parent_id} for d in query]
return { return {
"data": data} "data": data}
......
...@@ -759,6 +759,8 @@ def reset_password_validator(form, value): ...@@ -759,6 +759,8 @@ def reset_password_validator(form, value):
def security_code_age(user): def security_code_age(user):
now = create_now() now = create_now()
if user.security_code_date: if user.security_code_date:
if not user.security_code_date.tzinfo:
return now - user.security_code_date.replace(tzinfo=now.tzinfo)
return now - user.security_code_date return now - user.security_code_date
return timedelta(minutes=1) return timedelta(minutes=1)
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!