# your code goes here
class Field( object ) :
def __init__ ( self , name, column_type) :
self .name = name
self .column_type = column_type
def __str__ ( self ) :
return '<%s:%s>' % ( self .__class__.__name__, self .name )
class StringField( Field) :
def __init__ ( self , name) :
super ( StringField, self ) .__init__ ( name, 'varchar(100)' )
class IntegerField( Field) :
def __init__ ( self , name) :
super ( IntegerField, self ) .__init__ ( name, 'bigint' )
class ModelMetaclass( type ) :
def __new__ ( cls, name, bases, attrs) :
if name== 'Model' :
return type .__new__ ( cls, name, bases, attrs)
print ( 'Found model: %s' % name)
mappings = dict ( )
for k, v in attrs.items ( ) :
if isinstance ( v, Field) :
print ( 'Found mapping: %s ==> %s' % ( k, v) )
mappings[ k] = v
for k in mappings.keys ( ) :
attrs.pop ( k)
attrs[ '__mappings__' ] = mappings # 保存属性和列的映射关系
attrs[ '__table__' ] = name # 假设表名和类名一致
return type .__new__ ( cls, name, bases, attrs)
class Model( dict , metaclass= ModelMetaclass) :
def __init__ ( self , **kw) :
super ( Model, self ) .__init__ ( **kw)
def __getattr__ ( self , key) :
try :
temp= self [ key]
print ( 'quoted' )
return temp
except KeyError :
raise AttributeError ( r"'Model' object has no attribute '%s'" % key)
def __setattr__ ( self , key, value) :
self [ key] = value
def save( self ) :
fields = [ ]
params = [ ]
args = [ ]
for k, v in self .__mappings__.items ( ) :
fields.append ( v.name )
params.append ( '?' )
args.append ( getattr ( self , k, None ) )
sql = 'insert into %s (%s) values (%s)' % ( self .__table__, ',' .join ( fields) , ',' .join ( params) )
print ( 'SQL: %s' % sql)
print ( 'ARGS: %s' % str ( args) )
class User( Model) :
# 定义类的属性到列的映射:
id = IntegerField( 'id' )
name = StringField( 'username' )
email = StringField( 'email' )
password = StringField( 'password' )
# 创建一个实例:
u = User( id = 12345 , name= 'Michael' , email = 'test@orm.org' , password= 'my-pwd' )
# 保存到数据库:
u.save ( )
IyB5b3VyIGNvZGUgZ29lcyBoZXJlCmNsYXNzIEZpZWxkKG9iamVjdCk6CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUsIGNvbHVtbl90eXBlKToKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCiAgICAgICAgc2VsZi5jb2x1bW5fdHlwZSA9IGNvbHVtbl90eXBlCgogICAgZGVmIF9fc3RyX18oc2VsZik6CiAgICAgICAgcmV0dXJuICc8JXM6JXM+JyAlIChzZWxmLl9fY2xhc3NfXy5fX25hbWVfXywgc2VsZi5uYW1lKQoKY2xhc3MgU3RyaW5nRmllbGQoRmllbGQpOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG5hbWUpOgogICAgICAgIHN1cGVyKFN0cmluZ0ZpZWxkLCBzZWxmKS5fX2luaXRfXyhuYW1lLCAndmFyY2hhcigxMDApJykKCmNsYXNzIEludGVnZXJGaWVsZChGaWVsZCk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSk6CiAgICAgICAgc3VwZXIoSW50ZWdlckZpZWxkLCBzZWxmKS5fX2luaXRfXyhuYW1lLCAnYmlnaW50JykKCmNsYXNzIE1vZGVsTWV0YWNsYXNzKHR5cGUpOgogICAgZGVmIF9fbmV3X18oY2xzLCBuYW1lLCBiYXNlcywgYXR0cnMpOgogICAgICAgIGlmIG5hbWU9PSdNb2RlbCc6CiAgICAgICAgICAgIHJldHVybiB0eXBlLl9fbmV3X18oY2xzLCBuYW1lLCBiYXNlcywgYXR0cnMpCiAgICAgICAgcHJpbnQoJ0ZvdW5kIG1vZGVsOiAlcycgJSBuYW1lKQogICAgICAgIG1hcHBpbmdzID0gZGljdCgpCiAgICAgICAgZm9yIGssIHYgaW4gYXR0cnMuaXRlbXMoKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZSh2LCBGaWVsZCk6CiAgICAgICAgICAgICAgICBwcmludCgnRm91bmQgbWFwcGluZzogJXMgPT0+ICVzJyAlIChrLCB2KSkKICAgICAgICAgICAgICAgIG1hcHBpbmdzW2tdID0gdgogICAgICAgIGZvciBrIGluIG1hcHBpbmdzLmtleXMoKToKICAgICAgICAgICAgYXR0cnMucG9wKGspCiAgICAgICAgYXR0cnNbJ19fbWFwcGluZ3NfXyddID0gbWFwcGluZ3MgIyDkv53lrZjlsZ7mgKflkozliJfnmoTmmKDlsITlhbPns7sKICAgICAgICBhdHRyc1snX190YWJsZV9fJ10gPSBuYW1lICMg5YGH6K6+6KGo5ZCN5ZKM57G75ZCN5LiA6Ie0CiAgICAgICAgcmV0dXJuIHR5cGUuX19uZXdfXyhjbHMsIG5hbWUsIGJhc2VzLCBhdHRycykKICAgICAgICAKY2xhc3MgTW9kZWwoZGljdCwgbWV0YWNsYXNzPU1vZGVsTWV0YWNsYXNzKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCAqKmt3KToKICAgICAgICBzdXBlcihNb2RlbCwgc2VsZikuX19pbml0X18oKiprdykKCiAgICBkZWYgX19nZXRhdHRyX18oc2VsZiwga2V5KToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHRlbXA9c2VsZltrZXldCiAgICAgICAgICAgIHByaW50KCdxdW90ZWQnKQogICAgICAgICAgICByZXR1cm4gdGVtcAogICAgICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICAgICAgcmFpc2UgQXR0cmlidXRlRXJyb3IociInTW9kZWwnIG9iamVjdCBoYXMgbm8gYXR0cmlidXRlICclcyciICUga2V5KQoKICAgIGRlZiBfX3NldGF0dHJfXyhzZWxmLCBrZXksIHZhbHVlKToKICAgICAgICBzZWxmW2tleV0gPSB2YWx1ZQoKICAgIGRlZiBzYXZlKHNlbGYpOgogICAgICAgIGZpZWxkcyA9IFtdCiAgICAgICAgcGFyYW1zID0gW10KICAgICAgICBhcmdzID0gW10KICAgICAgICBmb3IgaywgdiBpbiBzZWxmLl9fbWFwcGluZ3NfXy5pdGVtcygpOgogICAgICAgICAgICBmaWVsZHMuYXBwZW5kKHYubmFtZSkKICAgICAgICAgICAgcGFyYW1zLmFwcGVuZCgnPycpCiAgICAgICAgICAgIGFyZ3MuYXBwZW5kKGdldGF0dHIoc2VsZiwgaywgTm9uZSkpCiAgICAgICAgc3FsID0gJ2luc2VydCBpbnRvICVzICglcykgdmFsdWVzICglcyknICUgKHNlbGYuX190YWJsZV9fLCAnLCcuam9pbihmaWVsZHMpLCAnLCcuam9pbihwYXJhbXMpKQogICAgICAgIHByaW50KCdTUUw6ICVzJyAlIHNxbCkKICAgICAgICBwcmludCgnQVJHUzogJXMnICUgc3RyKGFyZ3MpKQpjbGFzcyBVc2VyKE1vZGVsKToKICAgICMg5a6a5LmJ57G755qE5bGe5oCn5Yiw5YiX55qE5pig5bCE77yaCiAgICBpZCA9IEludGVnZXJGaWVsZCgnaWQnKQogICAgbmFtZSA9IFN0cmluZ0ZpZWxkKCd1c2VybmFtZScpCiAgICBlbWFpbCA9IFN0cmluZ0ZpZWxkKCdlbWFpbCcpCiAgICBwYXNzd29yZCA9IFN0cmluZ0ZpZWxkKCdwYXNzd29yZCcpCgojIOWIm+W7uuS4gOS4quWunuS+i++8mgp1ID0gVXNlcihpZD0xMjM0NSwgbmFtZT0nTWljaGFlbCcsIGVtYWlsPSd0ZXN0QG9ybS5vcmcnLCBwYXNzd29yZD0nbXktcHdkJykKIyDkv53lrZjliLDmlbDmja7lupPvvJoKdS5zYXZlKCkgIA==