SqlAlchemy:基于Python的ORM框架之数据库逆向工程(正向工程)- sqlacodegen

目录

时间过得真快

多因子数据库及数据API设计经验

数据库逆向工程


时间过得真快

感慨一声:都要2020了!

由于工作繁忙,已经不是学生时代,所以现在的文章数量少了很多。

不过,我争取写出一点高质量的体会,弥补数量上的缺憾。

 

最近在做多因子(数量化投资)的底层数据库及数据API基建工作。

看了不少基于关系型数据库的多因子数据库结构,也看了不少关于数据API的代码。

经过反复推敲,终于初步确定数据库的表结构、数据API的基本思路。

只要顶层设计得好,写代码是很快的。在此总结一些经验。

 

多因子数据库及数据API设计经验

我之前比较反感在Python里用ORM,而不是直接用SQL,是因为曾经见到的代码,拿着ORM这把牛刀去杀鸡。

请见我之前的文章《疑问:对于反三范式设计下的关系型数据库,是否需要ORM?》。

当时我提了三点不想用ORM的理由。

1. 当时的数据库不讲三范式,数据冗余得完全可以不用联合查询(单表可以涵盖很多内容)。

2. 页面展示。pandas的read_sql可以直接成为dataframe,而dataframe.to_html又可以直接成为<table></table>。当时的需求是前端展示以表格为主。当时我看见有人在类似DAO层(其实并没有分层)的地方,把table封装成object。握草,我到了View层又要把object转成table?

3. 尽管在切换数据库类型时,我们可以不用改DAO层的代码,但是当时一是我们没有切换数据库的需求,二是当时的代码可能就是三五个人写一写,再修修补补,既没有分层,又没有分模块。

 

现在,我却极力向大家推荐ORM。真香!

1. 我们现在的库满足三范式。我们用到的原生态数据库是专业数据机构设计的,三范式、主外键、约束,应有尽有。我们落地的数据库就是把原生态数据库拷贝了一份,一模一样。我们自己设计的因子库,因子表简单、统一,满足三范式。有时候还会出现基于“一对多”的“多”去查“一”,或是基于“一”去查“多”。ORM框架一般支持正向查询和反向查询。

2. 我们现在无需前端以表格的方式展示。给上层用户提供的数据查询API,通过输入证券代码、时间、因子名,返回二维表的形式。sql语句由sqlalchemy自主生成,pd.read_sql成df,传给上层。同时,我看中了不必自己用string拼接sql语句的功能。

3. 现在我们的原生态库是SQL Server,自己的备份落地库和因子库是MySQL。所以为了不重复写代码,用Sqlalchemy在DAO层与DB层之间架一座桥梁是有必要的。

4. 往后要接实盘交易,实盘的数据、订单,当然应该以对象的方式存在和处理,但数据库又是关系型数据库,正好发挥出ORM的优势。

 

经验就是:

1. 没有好不好的技术,只有适不适合的技术。

2. 如果用关系型数据库,尽量还是符合三范式。

不冗余,维护成本较低,数据一致性较高。选股票嘛,数据定了就定了,不能改了。你又不能活在未来,10月8日手里的数据只有这些,只能用这些。后期就算是修改了,在回测(backtesting)的时候,在日期=10月8日的那一天,你也不能用更新后的数据(未来数据)。

3. 横向分层,纵向分模块。多人协作,应该事先规定好接口(统一出一套标准)。尽管书上强调过很多次,但真正在实施的过程中,往往不会这么做。而结局当然也会是:自食其果、自讨苦吃。

4. 至于接实盘,要考虑自己在市场上是什么身份。投机者?套利?对冲

 

数据库逆向工程

我这里是基于Python的逆向工程。其他语言当然也有非常经典的框架,如Java的Hibernate。

根据已有的数据库,逆向生成model描述文件(关系-对象映射描述文件)。

一定要用CMD,不能用PowerShell,否则会出现编码的问题!

ValueError: source code string cannot contain null bytes

 

安装 sqlacodegen

pip install sqlacodegen

 

生成mysql的model

sqlacodegen mysql://root:root@localhost:3306/db_wind > models.py

 

生成sql server (mssql)的model

sqlacodegen mssql+pymssql://user:[email protected]:1433/jydb > jy_models.py

如果报错 ModuleNotFoundError: No module named 'MySQLdb',安装mysqlclient即可

pip install mysqlclient

如果报错 sqlalchemy.exc.InvalidRequestError: Could not reflect: requested table(s) not available in Engine(mssql+pymssql://root:***@xxx.xx.xx.x:1433/.....

可能是在命令行内表名没有区分大小写。比如,mssql表名要区分大小写。但,mysql在windows下好像数据库名和表名不区分大小写…这个只有自己协调了。

如果只需要生成某些表, --tables table_1,table_2

 

sqlacodegen的帮助

sqlacodegen -h

 

注意事项

如果字段名、表名、数据库名是中文,逆向生成models.py会出问题!

如果需要输出sql语句,创建引擎时,设置echo=True即可。

engine = create_engine('mysql+pymysql://qcy:[email protected]:3306/db_wind', echo=True)

 

创建表结构(根据model描述文件)

Base.metadata.create_all(engine)  # 创建表结构

凡是继承了Base的类,都会被创建成表


Drop所有表

Base.metadata.drop_all(engine)  # drop所有表

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章