1. 程式人生 > >Python-Flask:動態建立表的例項程式碼

Python-Flask:動態建立表的例項程式碼

今天小編從專案的實際出發,由於專案某一個表的資料達到好幾十萬條,此時資料的增刪查改會很慢;為了增加提高訪問的速度,我們引入動態建立表。

程式碼如下:

from app_factory import app
from sqlalchemy import Column, String, Integer

class ProjectModel(app.db.model, app.db.Mixin):

    tablename = 'Project_'

    ID = Column(String(50), name='ID', doc='id')
    PROJECTNUMBER = Column(String(100), name='PROJECTNUMBER', doc='專案編號')
    ......


    @staticmethod
    def create_table(project_number)
        table_name = ProjectModel.tablename + projectnumber
        structs = [
            {'fieldname': 'id', 'type': 'varchar2(50)', 'primary': True, 'default': ''},
            {'fieldname': 'PROJECTNUMBER', 'type': 'varchar2(50)', 'default': 0, 'isnull':                 
               True},
            .......
        ]
        app.db.create_table(table_name, structs)




那麼,內層函式是如何建立的呢?其實就是拼接sql語句create table ....

程式碼如下:

class SQLAlchemyDB(SQLAlchemy):
    def __init__(self, app)
        super(SQLAlchemyDB, self).__init__(app)
        self.__app = app
        self.engine.echo = False
        self.conn = self.engine.connect()
        self.Model.to_dict() = lambda self:{c.name:getattr(self, c.name, None) for c in self.__table__.columns}
        self.Session = sessionmaker(bind=self.engine)
        self.ScopedSession = lambda: scoped_session(self.Session)
 
    # 釋放碎片空間
    def free_idle_space(self):
        return self.execute('purge recyclebin')
    
    def connstatus(self):
        return self.engine.pool.status()
    
    def close(self):
        self.conn.close()
        self.engine.dispose()

    # 非返回資料的記錄語句
    def execute(self, sqlexpr)
        try:
            ret = self.conn.execute(sqlalchemy.text(sqlexpr))
        except Exception as err:
            return False, str(err)
        except sqlalchemy.exc.InvalidRequestError as err:
            return False, str(err)

        return True, ''

    # 動態拼接sql語句, 建立表
    def create_table(self, tablename, structs):
        fieldinfos = []
        for struct in structs:
            defaultvalue = struct.get('default')
            if defaultvalue :
                defaultvalue = "'{0}'".format(defaultvalue) if type(defaultvalue) == 'str' else str(defaultvalue)
            fieldinfos.append('{0} {1} {2} {3} {4}'.format(struct['fieldname'], struct['type'], 'primary key' if struct.get('primary') else '', ('default' + defaultvalue) if defaultvalue else '', '' if struct.get('isnull') else 'not null'))
        sql = 'create table {0} ({1})'.format(tablename, ','.join(fieldinfos))
        ret, err = self.execute(sql)
        if ret:
            self.__app.sync_record(tablename, 'sql_createtable', {}, sql)
        return ret, err

    # 動態判斷表是否存在 
    def existtable(self, tablename):
        ret, err = self.GetRecordCount("user_all_table", "TABLE_NAME='" + tablename +"'")
        return ret>0, err
    
    def GetRecordCount(self, tablename, where= None):
        sql = 'select count(*) as num from {0} {1}'.format(tablename,('where' + where)) if where != None else '')
        recs, err = self.query(sql)
        if recs:
            for rec in recs:
                return rec['num'], '' 
        return -1 , err
    
    # 查詢資料記錄
    def query(self, sqlexpr):
        try:
            recs = self.conn.execute(sqlalchemy.text(sqlexpr)
            return recs, ''
        expect Exception as err:
            return None, str(err)   
        expect sqlalchemy.exc.InvalidRequestError as err:
            return None, str(err)    

那麼,類似的:

1-如果動態的對已經建立的表格進行增刪查改,那麼可以用類似的思想,進行對sql語句進行拼接,insert  select  delete  update

2-判斷是否存在此欄位,進去拼接查詢這個欄位查出的資料是否為空(count)

3-在原來表的基礎上增加欄位,或者修改欄位,用alter