Skip to content

Instantly share code, notes, and snippets.

@kaka19ace
Last active August 29, 2015 14:23
Show Gist options
  • Save kaka19ace/749fb43bc441ac41a1b1 to your computer and use it in GitHub Desktop.
Save kaka19ace/749fb43bc441ac41a1b1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# @file model/model/base.py
# @author kaka_ace <[email protected]>
# @date
# @brief
#
from sqlalchemy.ext.declarative import (
declarative_base,
DeclarativeMeta,
)
from sqlalchemy.orm import aliased
from sqlalchemy import or_
class ModelMeta(DeclarativeMeta):
def __new__(cls, name, bases, d):
return DeclarativeMeta.__new__(cls, name, bases, d)
def __init__(self, name, bases, d):
DeclarativeMeta.__init__(self, name, bases, d)
_Base = declarative_base(metaclass=ModelMeta)
class BaseModel(_Base):
__abstract__ = True
_column_name_sets = NotImplemented
def get_py_dict(self):
"""
"""
return dict((column_name, getattr(self, column_name, None)) for column_name in self._column_name_sets)
def set_py_dict(self, data, check_key_sets=None):
"""
:param: data: dict of data
:param : check_key_sets: check nullable key sets, the structure should be set()
"""
if check_key_sets is not None:
if isinstance(check_key_sets, list):
check_key_sets = set(check_key_sets)
key_sets = set(dict().keys())
if not check_key_sets.issubset(key_sets):
raise KeyError(
"check_key_sets not match for data keys(not subset) check_key_sets {0} vs key_sets {1}".format(
check_key_sets, key_sets
)
)
for k, v in data.items():
if k in self._column_name_sets:
setattr(self, k, v)
@classmethod
def check_py_dict_integrity(cls, data):
"""
set Column Attribute from Python Dict
this output should not be printed
"""
key_sets = set(data.keys())
return cls._column_name_sets.issubset(key_sets)
@classmethod
def is_py_dict_key_in_column_sets(cls, data):
"""
set Column Attribute from Python Dict
this output should not be printed
可能有空集
"""
key_sets = set(data.keys())
return key_sets.issubset(cls._column_name_sets)
@classmethod
def get_attributes_sets(cls):
"""
"""
return cls._column_name_sets
@classmethod
def get_table_name_prefix(cls):
return cls._table_name_prefix
or_ = or_
__str__ = lambda self: str(self.get_py_dict())
__repr__ = lambda self: repr(self.get_py_dict())
def modelmeta__new__(cls, name, bases, namespace, **kwds):
column_name_sets = set()
for k, v in namespace.items():
if getattr(v, '__class__', None) is None:
continue
if v.__class__.__name__ == 'Column':
column_name_sets.add(k)
# obj = type.__new__(cls, name, bases, dict(namespace))
obj = DeclarativeMeta.__new__(cls, name, bases, dict(namespace))
# update set
if obj._column_name_sets is NotImplemented:
obj._column_name_sets = column_name_sets
else:
obj._column_name_sets.update(column_name_sets)
return obj
# modify BaseModel' metatype ModelMeta' __new__ definition
setattr(ModelMeta, '__new__', modelmeta__new__)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment