【Python小技巧】使用sqlite的内存数据库提高股票行情数据读写(附代码)


前言

SQLite是一种轻型的关系型数据库,可以嵌入到各种应用程序中。与传统的磁盘数据库不同,SQLite内存数据库将数据存储在内存中,从而提高了数据访问的速度和效率。在介绍SQLite内存数据库之前,我们先了解一下它的主要优点和使用方法。

主要优点
高速读写:由于数据存储在内存中,读写操作无需经过磁盘I/O,从而提高了数据处理速度。
跨平台兼容:SQLite支持多种操作系统,包括Windows、Linux、macOS等。
零配置:SQLite无需安装和配置,只需将库文件加入到项目中即可使用。
轻量级:SQLite内存数据库对系统资源的要求较低,适用于各种嵌入式系统。

一、内存中数据库

SQLite 内存中数据库是完全存储在内存中(而不是磁盘上)的数据库。 使用特殊数据源文件名 :memory: 可创建内存中数据库。 连接关闭后,数据库会被删除。 使用 :memory: 时,每个连接都会创建自己的数据库。

Data Source=:memory:

可共享的内存中数据库

在连接字符串中使用 Mode=Memory 和 Cache=Shared 可以在多个连接之间共享内存中数据库。 Data Source 关键字用于为内存中数据库提供名称。 使用相同名称的连接字符串将访问相同的内存中数据库。 只要至少有一个与之相连的连接保持打开状态,数据库便会保持。

Data Source=InMemorySample;Mode=Memory;Cache=Shared

二、使用步骤

1.引入库

import sqlite3,os

class KtSqlite:
    def __init__(self,db = "file:memdb1?mode=memory&cache=shared"):
        self.conn = sqlite3.connect(db)
        self.cur = self.conn.cursor()

    def get_tables(self):
        # sql = '''SHOW TABLES''' # mysql语句,sqlite使用如下语句
        # 查询数据库内所有表名
        sql = "SELECT name FROM sqlite_master WHERE type='table'"
        data = self.sql_execute(sql)
        tables_list = sorted([tuple[0] for tuple in data])
        return tables_list
    
    def sql_execute(self,sql):
        # 执行sql语句查询数据
        self.cur.execute(sql)
        data = self.cur.fetchall()
        return data
   
    def sqlite2df(self,sql):
        # 执行sql语句查询sqlite,读取数据到df
        import pandas as pd
        df = pd.read_sql_query(sql, self.conn)
        return df

    def df2sqlite(self,df,table_name):
        # 将df写入sqlite表
        # df.to_sql(table_name, self.conn, if_exists='replace', index=False)
        try:
            df.to_sql(table_name, self.conn, if_exists='replace', index=False)
        except Exception as e:
            log.logger.warning("df2sqlite执行失败!原因:"+str(e))
        else:
            return True

    def sqlite_close(self):
        # 关闭数据库
        self.cur.close()
        self.conn.close()
        print('Sqlite游标和连接已关闭')

# ===============表格美化输出===============
def df_table(df,index):
    import prettytable as pt
    #利用prettytable对输出结果进行美化,index为索引列名:df_table(df,'market')
    tb = pt.PrettyTable()
    # 如果为trade_time为index转换为日期类型,其它不用管。
    if index == "trade_time":
        df = df.set_index(index)
        df.index = pd.DatetimeIndex(df.index)
    # df.reset_index(level=None, drop=True, inplace=True, col_level=0, col_fill='')
    df = df.reset_index(drop = True)
    tb.add_column(index,df.index)#按date排序
    for col in df.columns.values:#df.columns.values的意思是获取列的名称
        # print('col',col)
        # print('df[col]',df[col])
        tb.add_column(col, df[col])
    print(tb)

if __name__ == '__main__':
    
    # 增加自定义函数及调用配置文件
    db = os.path.dirname(os.path.abspath(__file__))+"\\sqlite_stock.db" # 本地文件数据库
    dbmemory = ":memory:" # 一次性内存数据库
    dbm = "file:memdb1?mode=memory&cache=shared" # 共享式内存数据库
    # print('db',db)
    from Ashare import *
    ks = KtSqlite(db=dbm)
    df = get_price('000001.XSHG',frequency='15m',count=1000)  #支持'1m','5m','15m','30m','60m'
    print('上证指数分钟线\n',df)
    df_table(df.tail(20),'df')
    df['trade_time'] = df.index
    ret = ks.df2sqlite(df,'000001.XSHG')
    
    df2 = ks.sqlite2df("select * from '000001.XSHG'")
    print('上证指数分钟线\n',df2)
    df_table(df2.tail(20),'df2')
    
    ks.sqlite_close()

结果如下:

上证指数分钟线
                          open      high       low     close        volume

2023-11-27 13:15:00  3017.967  3025.775  3017.967  3025.502  1.504439e+09
2023-11-27 13:30:00  3025.785  3031.281  3023.081  3030.018  1.466044e+09
2023-11-27 13:45:00  3030.077  3035.020  3029.311  3033.609  1.344345e+09
2023-11-27 14:00:00  3033.420  3033.558  3026.858  3027.261  1.119192e+09
2023-11-27 14:15:00  3027.525  3028.896  3026.288  3027.924  1.031583e+09
...                       ...       ...       ...       ...           ...
2024-03-01 14:00:00  3015.785  3018.608  3011.751  3015.329  1.477684e+09
2024-03-01 14:15:00  3015.706  3026.758  3015.454  3023.326  1.754506e+09
2024-03-01 14:30:00  3023.693  3029.507  3022.647  3028.957  1.724464e+09
2024-03-01 14:45:00  3029.764  3032.231  3021.860  3022.380  2.047947e+09
2024-03-01 15:00:00  3022.464  3027.020  3022.169  3027.020  2.629162e+09

[1000 rows x 5 columns]
+----+----------+----------+----------+----------+--------------+
| df |   open   |   high   |   low    |  close   |    volume    |
+----+----------+----------+----------+----------+--------------+
| 0  | 2991.264 | 2991.881 | 2982.536 | 2982.943 | 1413397500.0 |
| 1  | 2982.599 | 2995.82  | 2982.43  | 2995.277 | 1644032300.0 |
| 2  | 2995.444 | 3005.413 | 2994.833 |  3005.4  | 2313589400.0 |
| 3  | 3005.494 | 3015.171 | 3004.951 | 3015.171 | 4025859600.0 |
| 4  | 3013.823 | 3021.554 | 3003.763 | 3008.55  | 7767234900.0 |
| 5  | 3008.463 | 3014.573 | 3003.942 | 3014.189 | 3769877000.0 |
| 6  | 3013.787 | 3018.727 | 3009.813 | 3016.104 | 2959926300.0 |
| 7  | 3015.805 | 3020.062 | 3015.079 | 3018.357 | 2323717400.0 |
| 8  | 3018.243 | 3019.163 | 3007.549 | 3013.008 | 2229002400.0 |
| 9  | 3013.117 | 3022.311 | 3011.737 | 3021.334 | 1524028200.0 |
| 10 | 3021.329 | 3024.891 | 3017.95  | 3024.543 | 1393396000.0 |
| 11 | 3024.598 | 3024.68  | 3014.09  | 3017.814 | 1485624400.0 |
| 12 | 3018.233 | 3019.336 | 3008.551 | 3008.713 | 1825591500.0 |
| 13 | 3008.837 | 3016.08  | 3008.77  | 3014.605 | 1506145700.0 |
| 14 | 3014.834 | 3018.749 | 3013.985 | 3015.78  | 1494911900.0 |
| 15 | 3015.785 | 3018.608 | 3011.751 | 3015.329 | 1477683600.0 |
| 16 | 3015.706 | 3026.758 | 3015.454 | 3023.326 | 1754505600.0 |
| 17 | 3023.693 | 3029.507 | 3022.647 | 3028.957 | 1724464300.0 |
| 18 | 3029.764 | 3032.231 | 3021.86  | 3022.38  | 2047947000.0 |
| 19 | 3022.464 | 3027.02  | 3022.169 | 3027.02  | 2629162200.0 |
+----+----------+----------+----------+----------+--------------+
上证指数分钟线
          open      high       low     close        volume           trade_time
0    3017.967  3025.775  3017.967  3025.502  1.504439e+09  2023-11-27 13:15:00
1    3025.785  3031.281  3023.081  3030.018  1.466044e+09  2023-11-27 13:30:00
2    3030.077  3035.020  3029.311  3033.609  1.344345e+09  2023-11-27 13:45:00
3    3033.420  3033.558  3026.858  3027.261  1.119192e+09  2023-11-27 14:00:00
4    3027.525  3028.896  3026.288  3027.924  1.031583e+09  2023-11-27 14:15:00
..        ...       ...       ...       ...           ...                  ...
995  3015.785  3018.608  3011.751  3015.329  1.477684e+09  2024-03-01 14:00:00
996  3015.706  3026.758  3015.454  3023.326  1.754506e+09  2024-03-01 14:15:00
997  3023.693  3029.507  3022.647  3028.957  1.724464e+09  2024-03-01 14:30:00
998  3029.764  3032.231  3021.860  3022.380  2.047947e+09  2024-03-01 14:45:00
999  3022.464  3027.020  3022.169  3027.020  2.629162e+09  2024-03-01 15:00:00

[1000 rows x 6 columns]
+-----+----------+----------+----------+----------+--------------+---------------------+
| df2 |   open   |   high   |   low    |  close   |    volume    |      trade_time     |
+-----+----------+----------+----------+----------+--------------+---------------------+
|  0  | 2991.264 | 2991.881 | 2982.536 | 2982.943 | 1413397500.0 | 2024-02-29 14:15:00 |
|  1  | 2982.599 | 2995.82  | 2982.43  | 2995.277 | 1644032300.0 | 2024-02-29 14:30:00 |
|  2  | 2995.444 | 3005.413 | 2994.833 |  3005.4  | 2313589400.0 | 2024-02-29 14:45:00 |
|  3  | 3005.494 | 3015.171 | 3004.951 | 3015.171 | 4025859600.0 | 2024-02-29 15:00:00 |
|  4  | 3013.823 | 3021.554 | 3003.763 | 3008.55  | 7767234900.0 | 2024-03-01 09:45:00 |
|  5  | 3008.463 | 3014.573 | 3003.942 | 3014.189 | 3769877000.0 | 2024-03-01 10:00:00 |
|  6  | 3013.787 | 3018.727 | 3009.813 | 3016.104 | 2959926300.0 | 2024-03-01 10:15:00 |
|  7  | 3015.805 | 3020.062 | 3015.079 | 3018.357 | 2323717400.0 | 2024-03-01 10:30:00 |
|  8  | 3018.243 | 3019.163 | 3007.549 | 3013.008 | 2229002400.0 | 2024-03-01 10:45:00 |
|  9  | 3013.117 | 3022.311 | 3011.737 | 3021.334 | 1524028200.0 | 2024-03-01 11:00:00 |
|  10 | 3021.329 | 3024.891 | 3017.95  | 3024.543 | 1393396000.0 | 2024-03-01 11:15:00 |
|  11 | 3024.598 | 3024.68  | 3014.09  | 3017.814 | 1485624400.0 | 2024-03-01 11:30:00 |
|  12 | 3018.233 | 3019.336 | 3008.551 | 3008.713 | 1825591500.0 | 2024-03-01 13:15:00 |
|  13 | 3008.837 | 3016.08  | 3008.77  | 3014.605 | 1506145700.0 | 2024-03-01 13:30:00 |
|  14 | 3014.834 | 3018.749 | 3013.985 | 3015.78  | 1494911900.0 | 2024-03-01 13:45:00 |
|  15 | 3015.785 | 3018.608 | 3011.751 | 3015.329 | 1477683600.0 | 2024-03-01 14:00:00 |
|  16 | 3015.706 | 3026.758 | 3015.454 | 3023.326 | 1754505600.0 | 2024-03-01 14:15:00 |
|  17 | 3023.693 | 3029.507 | 3022.647 | 3028.957 | 1724464300.0 | 2024-03-01 14:30:00 |
|  18 | 3029.764 | 3032.231 | 3021.86  | 3022.38  | 2047947000.0 | 2024-03-01 14:45:00 |
|  19 | 3022.464 | 3027.02  | 3022.169 | 3027.02  | 2629162200.0 | 2024-03-01 15:00:00 |
+-----+----------+----------+----------+----------+--------------+---------------------+
Sqlite游标和连接已关闭

总结

今天我们介绍了如何在内存中使用sqlite数据库。其中以下分别为不同形式的数据库,有兴趣的可以自行测试,对比读写速度。

    db = os.path.dirname(os.path.abspath(__file__))+"\\sqlite_stock.db" # 本地文件数据库
    dbmemory = ":memory:" # 一次性内存数据库
    dbm = "file:memdb1?mode=memory&cache=shared" # 共享式内存数据库
  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT里的交易员

分享是一种快乐,打赏是一种肯定

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值