python sqlalchemy 查询结果转化为 Json格式

时间:2024-11-20 18:58:22

      最近,给自己开发的软件平台开发第三方调用的API,如果返回结果集是json格式,其他语言开发就相对方便一些,网上找了好多资料没有找到特别合适的,最后下决心根据网上的资料改变自己写一个通用的。

此方法,主要应用场景是,Python 数据库框架 sqlalchemy 查询结果,转化成json格式。

# -*- coding: utf-8 -*-
import os
import json
import threading
 
from  import minidom
from  import declarative_base
from  import sessionmaker, scoped_session
from sqlalchemy import (create_engine,MetaData,Column,Integer,String)
from sqlalchemy import func
from  import and_, or_
from sqlalchemy import Table, Column, Integer, String, Text, DateTime, MetaData, ForeignKey, Boolean
from datetime import datetime
import time,uuid,re

Base = declarative_base()

#主机模型
class VirtualMachineContainer(Base):
    __tablename__ = 'virtual_machine_containers'

    id = Column(Integer, primary_key = True)
    hostname = Column(String(255))
    uuid = Column(String(255))
    address = Column(String(255))
    port = Column(Integer)
    status = Column(String(255))
    owner_id = Column(Integer)
    group_id = Column(Integer)
    cluster_id = Column(Integer)
    running_time = Column(Integer)
    cpu_type = Column(String(255))
    cpu_num = Column(String(255))
    cpu_usage = Column(String(255))
    mem_total = Column(String(255))
    mem_free = Column(String(255))
    disk_device = Column(String(255))
    disk_total = Column(String(255))
    disk_free = Column(String(255))
    nics_num = Column(Integer)
    net_ifname = Column(String(255))
    net_tx = Column(String(255))
    net_rx = Column(String(255))
    vm_name = Column(String(255))
    vm_state = Column(String(255))
    vcpu_usage = Column(String(255))
    vmem_total = Column(String(255))
    vmem_free = Column(String(255))
    vdisk_read = Column(String(255))
    vdisk_write = Column(String(255))
    vif_tx = Column(String(255))
    vif_rx = Column(String(255))
    field_metadata = Column('metadata', String(255))
    created_at = Column(DateTime, default=)
    updated_at = Column(DateTime, default=, onupdate=)
    vm_uuid = Column(Text)
    capability = Column(String(255))
    vdisk_names = Column(String(255))
    vif_names = Column(String(255))
    all_pair_ping = Column(Text)
    vnc_port = Column(String(255))
    vm_cnt = Column(Integer)
    respool_cnt = Column(String(255))
    reserved = Column(String(255))
    host_desc = Column(Text)
    host_vendor_name = Column(String(255))
    host_type = Column(String(255))
    oper_system_vendor_name = Column(String(255))
    oper_system_name = Column(String(255))
    uuid_bios = Column(String(255))
    dns = Column(String(255))
    cpu_core_num = Column(String(255))
    cpu_thread_num = Column(String(255))
    diskarray_num = Column(String(255))
    datacenter_id = Column(Integer, ForeignKey('data_centers.id'))
    user_name = Column(String(255))
    password = Column(String(255))
    status_flag = Column(Integer(1))
    hardware_id = Column(String(16))

def get_Session():
    #engine = create_engine('mysql://root:root@172.30.36.7/ivcs_portal?charset=utf8')
    engine = create_engine('mysql://root:@172.30.36.7/ivcs_portal?charset=utf8')
    .create_all(engine)
    Session =sessionmaker( autocommit=False, autoflush=False, bind=engine)
    return Session
from  import DeclarativeMeta
class AlchemyEncoder():
    def default(self, obj):
        if isinstance(obj.__class__, DeclarativeMeta):
            # an SQLAlchemy class
            fields = {}
            for field in [x for x in dir(obj) if not ('_') and x != 'metadata']:
                data = obj.__getattribute__(field)
                try:
                    if isinstance(data, datetime): 
                        data=('%Y-%m-%d %H:%M:%S') 
                    (data) # this will fail on non-encodable values, like other classes
                    fields[field] = data
                except TypeError:
                    fields[field] = None
            # a json-encodable dict
            return fields
    
        return (self, obj)
def new_alchemy_encoder():
    _visited_objs = []
    class AlchemyEncoder():
        def default(self, obj):
            if isinstance(obj.__class__, DeclarativeMeta):
                # don't re-visit self
                if obj in _visited_objs:
                    return None
                _visited_objs.append(obj)

                # an SQLAlchemy class
                fields = {}
                for field in [x for x in dir(obj) if not ('_') and x != 'metadata']:
                    data = obj.__getattribute__(field)
                    try:
                        if isinstance(data, datetime): 
                            data=('%Y-%m-%d %H:%M:%S') 
                        (data) # this will fail on non-encodable values, like other classes
                        fields[field] = data
                    except TypeError:
                        fields[field] = None
                return fields

            return (self, obj)
    return AlchemyEncoder

def testjson():
    session=get_Session()()
    vmcs = (VirtualMachineContainer).all()
    try:
        
        Hosts =[]
        for vmc in vmcs:
            #print (vmc, cls=AlchemyEncoder)
            (vmc)
        print (Hosts, cls=new_alchemy_encoder(), check_circular=False)
    except Exception, e:
        print e  

if __name__ == '__main__':
    testjson()