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.
""" """
...@@ -335,6 +343,21 @@ def main(global_config, **settings): ...@@ -335,6 +343,21 @@ def main(global_config, **settings):
# None: {"js": "opensipkd.base:static/jquery/jquery.maskMoney.min.js"}} # None: {"js": "opensipkd.base:static/jquery/jquery.maskMoney.min.js"}}
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:
......
...@@ -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', # 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',
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)
...@@ -14,11 +15,11 @@ class _Departemen(NamaModel): ...@@ -14,11 +15,11 @@ class _Departemen(NamaModel):
singkat = Column(String(32)) singkat = Column(String(32))
level_id = Column(SmallInteger) level_id = Column(SmallInteger)
__tablename__ = 'departemen' __tablename__ = 'departemen'
@declared_attr @declared_attr
def children(self): def children(self):
return relationship( return relationship(
"Departemen", backref=backref('parent', remote_side=[self.id])) "Departemen", backref=backref('parent', remote_side=[self.id]))
def get_parents(self, start=False): def get_parents(self, start=False):
allparents = [] allparents = []
...@@ -47,7 +48,7 @@ class _Departemen(NamaModel): ...@@ -47,7 +48,7 @@ class _Departemen(NamaModel):
@classmethod @classmethod
def get_list(cls): def get_list(cls):
return DBSession.query(cls.id, cls.nama).order_by(cls.nama).all() return DBSession.query(cls.id, cls.nama).order_by(cls.nama).all()
@classmethod @classmethod
def cte_get(cls, search=None, **kwargs): def cte_get(cls, search=None, **kwargs):
# tahun = kwargs.get('tahun', self.req.params.get( # tahun = kwargs.get('tahun', self.req.params.get(
...@@ -55,57 +56,78 @@ class _Departemen(NamaModel): ...@@ -55,57 +56,78 @@ 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"
sql = """ eng = cls.db_session.get_bind()
WITH RECURSIVE dep_tree AS ( if eng.dialect.name.lower() == "oracle":
SELECT sql = """
id, SELECT
kode, --LPAD(' ', (LEVEL - 1) * 2) || nama AS hierarchy,
nama, SYS_CONNECT_BY_PATH(nama, '/') AS hierarchy,
parent_id, id,
status, kode,
0 AS level, nama,
ARRAY[id] AS path parent_id,
FROM status,
public.departemen (LEVEL - 1) AS lvl,
WHERE SYS_CONNECT_BY_PATH(id, ',') AS path
{str_where} FROM
UNION ALL departemen
START WITH
SELECT parent_id IS NULL
c.id, CONNECT BY
c.kode, PRIOR id = parent_id
c.nama, ORDER SIBLINGS BY
c.parent_id, id"""
c.status, else:
ct.level + 1, sql = """
ct.path || c.id WITH RECURSIVE dep_tree AS (
FROM SELECT
public.departemen c id,
kode,
JOIN nama,
dep_tree ct ON c.parent_id = ct.id parent_id,
) status,
SELECT 0 AS lvl,
REPEAT(' ', level) || nama AS hierarchy, -- Indent names based on level ARRAY[id] AS path
id, FROM
kode, public.departemen
nama, WHERE
parent_id, {str_where}
status, UNION ALL
level,
path SELECT
FROM c.id,
dep_tree c.kode,
""".format(str_where=str_where) c.nama,
c.parent_id,
if search: c.status,
sql = f"{sql} WHERE nama ILIKE '%{search}%' " ct.level + 1,
ct.path || c.id
sql=sql+"""ORDER BY path;""" FROM
public.departemen c
JOIN
dep_tree ct ON c.parent_id = ct.id
)
SELECT
REPEAT(' ', lvl) || nama AS hierarchy, -- Indent names based on level
id,
kode,
nama,
parent_id,
status,
level,
path
FROM
dep_tree
""".format(str_where=str_where)
if search:
sql = f"{sql} WHERE nama ILIKE '%{search}%' "
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!