Add error handling for table creation in Alembic migrations

1 parent 884d29c3
......@@ -18,6 +18,7 @@ depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
try:
op.create_table('eselon',
sa.Column('pangkat', sa.String(length=32), nullable=True),
sa.Column('ruang', sa.String(length=1), nullable=True),
......@@ -29,10 +30,14 @@ def upgrade():
sa.Column('updated', sa.DateTime(), nullable=True),
sa.Column('create_uid', sa.Integer(), nullable=True),
sa.Column('update_uid', sa.Integer(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('id', sa.Integer(), sa.Identity(always=True),
primary_key=True, nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_eselon')),
# schema='public'
)
except Exception as e:
print(str(e))
try:
op.create_table('pangkat',
sa.Column('pangkat', sa.String(length=32), nullable=True),
sa.Column('ruang', sa.String(length=1), nullable=True),
......@@ -43,10 +48,14 @@ def upgrade():
sa.Column('updated', sa.DateTime(), nullable=True),
sa.Column('create_uid', sa.Integer(), nullable=True),
sa.Column('update_uid', sa.Integer(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('id', sa.Integer(), sa.Identity(always=True),
primary_key=True, nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_pangkat')),
# schema='public'
)
except Exception as e:
print(str(e))
try:
op.create_table('jabatan',
sa.Column('jenis', sa.SmallInteger(), nullable=True),
sa.Column('nama_lain', sa.String(
......@@ -61,19 +70,24 @@ def upgrade():
sa.Column('updated', sa.DateTime(), nullable=True),
sa.Column('create_uid', sa.Integer(), nullable=True),
sa.Column('update_uid', sa.Integer(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('id', sa.Integer(), sa.Identity(always=True),
primary_key=True, nullable=False),
sa.ForeignKeyConstraint(['eselon_id'], ['eselon.id'], name=op.f(
'fk_jabatan_eselon_id_eselon')),
sa.PrimaryKeyConstraint('id', name=op.f('pk_jabatan')),
# schema='public'
)
except Exception as e:
print(str(e))
try:
op.create_table('partner_departemen',
sa.Column('partner_id', sa.Integer(), nullable=True),
sa.Column('departemen_id', sa.Integer(), nullable=True),
sa.Column('jabatan_id', sa.SmallInteger(), nullable=True),
sa.Column('mulai', sa.DateTime(), nullable=True),
sa.Column('selesai', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('id', sa.Integer(), sa.Identity(always=True),
primary_key=True, nullable=False),
sa.ForeignKeyConstraint(['departemen_id'], ['departemen.id'], name=op.f(
'fk_partner_departemen_departemen_id_departemen')),
sa.ForeignKeyConstraint(['jabatan_id'], ['jabatan.id'], name=op.f(
......@@ -86,6 +100,9 @@ def upgrade():
'jabatan_id', 'mulai', name='partner_dept_uq'),
# schema='public'
)
except Exception as e:
print(str(e))
# ### end Alembic commands ###
......
......@@ -30,7 +30,8 @@ def upgrade():
sa.Column('updated', sa.DateTime(), nullable=True),
sa.Column('create_uid', sa.Integer(), nullable=True),
sa.Column('update_uid', sa.Integer(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('id', sa.Integer(), sa.Identity(always=True),
primary_key=True , nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_text_printers')),
# schema='public'
)
......
from datetime import datetime, timezone
import sqlalchemy as sa
class ForceUTCDatetime(sa.TypeDecorator):
"""Ensures datetimes are timezone-aware UTC objects across both DBs."""
impl = sa.TIMESTAMP(timezone=True)
cache_ok = True
def process_bind_param(self, value, dialect):
if value is not None:
if value.tzinfo is None:
# Interpret naive datetime as UTC or handle according to business logic
value = value.replace(tzinfo=timezone.utc)
else:
# Convert any other timezone directly to UTC
value = value.astimezone(timezone.utc)
return value
def process_result_value(self, value, dialect):
if value is not None and value.tzinfo is None:
# Force the Python object to be aware if Oracle stripped the offset
return value.replace(tzinfo=timezone.utc)
return value
from .meta import *
from .common import *
from .base import *
......
......@@ -59,7 +59,7 @@ class _Departemen(NamaModel):
eng = cls.db_session.get_bind()
if eng.dialect.name.lower() == "oracle":
sql = """
SELECT
SELECT
--LPAD(' ', (LEVEL - 1) * 2) || nama AS hierarchy,
SYS_CONNECT_BY_PATH(nama, '/') AS hierarchy,
id,
......@@ -69,62 +69,56 @@ SELECT
status,
(LEVEL - 1) AS lvl,
SYS_CONNECT_BY_PATH(id, ',') AS path
FROM
FROM
departemen
START WITH
START WITH
parent_id IS NULL
CONNECT BY
CONNECT BY
PRIOR id = parent_id
ORDER SIBLINGS BY
id"""
ORDER SIBLINGS BY
id """
else:
sql = """
WITH RECURSIVE dep_tree AS (
WITH RECURSIVE dep_tree AS (
SELECT
id,
kode,
nama,
nama::text AS nama,
parent_id,
status,
0 AS lvl,
ARRAY[id] AS path
FROM
public.departemen
WHERE
{str_where}
FROM departemen
UNION ALL
SELECT
c.id,
c.kode,
c.nama,
ct.nama || '/' || c.nama::text AS nama,
c.parent_id,
c.status,
ct.level + 1,
ct.lvl + 1,
ct.path || c.id
FROM
public.departemen c
JOIN
dep_tree ct ON c.parent_id = ct.id
FROM departemen c
JOIN dep_tree ct ON c.parent_id = ct.id
)
SELECT
REPEAT(' ', lvl) || nama AS hierarchy, -- Indent names based on level
SELECT DISTINCT ON (kode)
id,
kode,
nama,
nama as hierarchy,
parent_id,
status,
level,
lvl,
path
FROM
dep_tree
""".format(str_where=str_where)
FROM dep_tree
"""
#.format(str_where=str_where)
if search:
sql = f"{sql} WHERE nama ILIKE '%{search}%' "
sql = sql+"""ORDER BY path;"""
sql = sql+"""ORDER BY kode, path """
return cls.db_session.execute(text(sql)).fetchall()
......
from datetime import datetime
import logging
from math import log
from requests import session
import pytz
import sqlalchemy as sa
from pyramid.authorization import (Allow, Authenticated, ALL_PERMISSIONS)
# from sqlalchemy import TIMESTAMP
from sqlalchemy import (
Column, Integer, DateTime, SmallInteger, String)
from sqlalchemy.orm import (relationship, backref)
......@@ -28,7 +26,7 @@ from opensipkd.tools import as_timezone
from .base import CommonModel, DBSession, DefaultModel
from .meta import Base
from .base import TABLE_ARGS
from . import ForceUTCDatetime
log = logging.getLogger(__name__)
class _GroupPermission(GroupPermissionMixin):
pass
......@@ -93,7 +91,7 @@ class _UserResourcePermission(UserResourcePermissionMixin):
class UserResourcePermission(_UserResourcePermission, Base):
pass
from sqlalchemy import TIMESTAMP
class _User(UserMixin, BaseModel):
db_session = DBSession
last_login_date = Column(DateTime(timezone=True), nullable=True)
......@@ -106,7 +104,8 @@ class _User(UserMixin, BaseModel):
# 'Asia/Jakarta')),
# server_default="2000-01-01 01:01+7",
# )
security_code_date = Column(TIMESTAMP(timezone=True))
# security_code_date = Column(TIMESTAMP(timezone=True))
security_code_date = Column(ForceUTCDatetime)
api_key = Column(String(256))
partner_id = Column(Integer) # , ForeignKey(Partner.id))
company_id = Column(Integer) # , ForeignKey(Partner.id))
......
......@@ -179,7 +179,10 @@ class Views(BaseView):
url_dict = request.matchdict
if url_dict['act'] == 'grid':
query = Departemen.cte_get()
data = [{"id": d.id, "kode": d.kode, "nama": d.hierarchy[1:], "status": d.status,
data = [{"id": d.id, "kode": d.kode,
"nama": d.hierarchy.startswith(
'/') and d.hierarchy[1:] or d.hierarchy,
"status": d.status,
"level_id": d.lvl, "parent_id": d.parent_id} for d in query]
return {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!