mirror of https://github.com/veops/cmdb.git
123 lines
4.0 KiB
Python
123 lines
4.0 KiB
Python
# -*- coding:utf-8 -*-
|
|
|
|
import datetime
|
|
|
|
import six
|
|
|
|
from api.extensions import db
|
|
from api.lib.exception import CommitException
|
|
|
|
|
|
class FormatMixin(object):
|
|
def to_dict(self):
|
|
return dict([(k.name, isinstance(getattr(self, k.name), datetime.datetime) and
|
|
getattr(self, k.name).strftime('%Y-%m-%d %H:%M:%S')) or
|
|
getattr(self, k.name) for k in getattr(self, "__table__").columns])
|
|
|
|
@classmethod
|
|
def get_columns(cls):
|
|
return {k.name: 1 for k in getattr(cls, "__mapper__").c.values()}
|
|
|
|
|
|
class CRUDMixin(FormatMixin):
|
|
@classmethod
|
|
def create(cls, flush=False, **kwargs):
|
|
return cls(**kwargs).save(flush=flush)
|
|
|
|
def update(self, flush=False, **kwargs):
|
|
kwargs.pop("id", None)
|
|
for attr, value in six.iteritems(kwargs):
|
|
if value is not None:
|
|
setattr(self, attr, value)
|
|
if flush:
|
|
return self.save(flush=flush)
|
|
return self.save()
|
|
|
|
def save(self, commit=True, flush=False):
|
|
db.session.add(self)
|
|
try:
|
|
if flush:
|
|
db.session.flush()
|
|
elif commit:
|
|
db.session.commit()
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
raise CommitException(str(e))
|
|
|
|
return self
|
|
|
|
def delete(self, flush=False):
|
|
db.session.delete(self)
|
|
try:
|
|
if flush:
|
|
return db.session.flush()
|
|
return db.session.commit()
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
raise CommitException(str(e))
|
|
|
|
def soft_delete(self, flush=False):
|
|
setattr(self, "deleted", True)
|
|
setattr(self, "deleted_at", datetime.datetime.now())
|
|
self.save(flush=flush)
|
|
|
|
@classmethod
|
|
def get_by_id(cls, _id):
|
|
if any((isinstance(_id, six.string_types) and _id.isdigit(),
|
|
isinstance(_id, (int, float))), ):
|
|
return getattr(cls, "query").get(int(_id)) or None
|
|
|
|
@classmethod
|
|
def get_by(cls, first=False, to_dict=True, fl=None, exclude=None, deleted=False, use_master=False, **kwargs):
|
|
db_session = db.session if not use_master else db.session().using_bind("master")
|
|
fl = fl.strip().split(",") if fl and isinstance(fl, six.string_types) else (fl or [])
|
|
exclude = exclude.strip().split(",") if exclude and isinstance(exclude, six.string_types) else (exclude or [])
|
|
|
|
keys = cls.get_columns()
|
|
fl = [k for k in fl if k in keys]
|
|
fl = [k for k in keys if k not in exclude and not k.isupper()] if exclude else fl
|
|
fl = list(filter(lambda x: "." not in x, fl))
|
|
|
|
if hasattr(cls, "deleted") and deleted is not None:
|
|
kwargs["deleted"] = deleted
|
|
|
|
if fl:
|
|
query = db_session.query(*[getattr(cls, k) for k in fl])
|
|
query = query.filter_by(**kwargs)
|
|
result = [{k: getattr(i, k) for k in fl} for i in query]
|
|
else:
|
|
result = [i.to_dict() if to_dict else i for i in getattr(cls, 'query').filter_by(**kwargs)]
|
|
|
|
return result[0] if first and result else (None if first else result)
|
|
|
|
@classmethod
|
|
def get_by_like(cls, to_dict=True, **kwargs):
|
|
query = db.session.query(cls)
|
|
for k, v in kwargs.items():
|
|
query = query.filter(getattr(cls, k).ilike('%{0}%'.format(v)))
|
|
return [i.to_dict() if to_dict else i for i in query]
|
|
|
|
|
|
class SoftDeleteMixin(object):
|
|
deleted_at = db.Column(db.DateTime)
|
|
deleted = db.Column(db.Boolean, index=True, default=False)
|
|
|
|
|
|
class TimestampMixin(object):
|
|
created_at = db.Column(db.DateTime, default=lambda: datetime.datetime.now())
|
|
updated_at = db.Column(db.DateTime, onupdate=lambda: datetime.datetime.now())
|
|
|
|
|
|
class SurrogatePK(object):
|
|
__table_args__ = {"extend_existing": True}
|
|
|
|
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
|
|
|
|
|
class Model(SoftDeleteMixin, TimestampMixin, CRUDMixin, db.Model, SurrogatePK):
|
|
__abstract__ = True
|
|
|
|
|
|
class CRUDModel(db.Model, CRUDMixin):
|
|
__abstract__ = True
|