对 SQL 很陌生,在这里使用烧瓶和 sqlalchemy 是我的问题(我希望它不会太长)
概述:
我有一个结构如下的 SQL 表:
name vector axis value unit ref
----------------------------------------------------------------
name1 v1 W 46504 psi ref1
name1 v1 L 51757 psi ref1
name1 v2 W 127 psi another ref
name1 v2 L 403 psi ref1
name2 ...
name
我的目标是“取消堆叠”结果,例如只要unit
并且ref
相同,我就可以拥有一行。
例如,我希望得到类似的东西:
name v1-L v2-W v1-L v2-W unit ref
--------------------------------------------------------------
name1 46504 127 403 psi ref1
name1 127 psi another ref
name2...
尝试使用 sqlalchemy:
到目前为止,我尝试根据“名称”加入同一张表——现在,两者都没有检查unit
—— ref
:
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, Table, Text, Date, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, aliased
engine = create_engine('sqlite://') #, echo=True)
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
class Test(Base):
__tablename__ = 'test'
id = Column(Integer, primary_key=True)
name = Column(String(32))
vector = Column(String(32))
axis = Column(String(1))
value = Column(Float)
unit = Column(String(16), default='psi')
ref = Column(String(32))
Base.metadata.create_all(engine)
# some data to play with
data = [{'name':'name1', 'vector':'v1', 'axis':'W', 'value':'46504', 'unit':'psi', 'ref':'ref1'},
{'name':'name1', 'vector':'v1', 'axis':'L', 'value':'51757', 'unit':'psi', 'ref':'ref1'},
{'name':'name1', 'vector':'v2', 'axis':'W', 'value':'127', 'unit':'psi', 'ref':'another ref'},
{'name':'name1', 'vector':'v2', 'axis':'L', 'value':'403', 'unit':'psi', 'ref':'ref1'},
{'name':'name2', 'vector':'v1', 'axis':'L', 'value':'23000', 'unit':'psi', 'ref':'ref1'},
{'name':'name2', 'vector':'v1', 'axis':'W', 'value':'27000', 'unit':'psi', 'ref':'ref1'},
{'name':'name2', 'vector':'v2', 'axis':'L', 'value':'523', 'unit':'psi', 'ref':'ref1'},
{'name':'name2', 'vector':'v2', 'axis':'W', 'value':'217', 'unit':'psi', 'ref':'ref1'},]
for dic in data:
t = Test(**dic)
session.add(t)
session.commit()
test_alias = aliased(Test)
q = session.query(Test.id, Test.name, Test.value).filter(Test.vector == 'v1').\
join(test_alias, Test.name).filter(test_alias.vector == 'v2')
print q
使用熊猫的示例:
这是我使用pandas
库会得到的。
import pandas as pd
q = session.query(Test).order_by(Test.id) # that is the default table
row2dict = lambda r: {c.name: getattr(r, c.name) for c in r.__table__.columns}
df = pd.DataFrame([row2dict(i) for i in q])
df = df.drop(['id'], axis=1)
df = df.set_index(['ref', 'unit', 'name', 'vector', 'axis']).sort()
df = df.unstack(level=-2).unstack(level=-1)['value'].reset_index()
print(df)
vector ref unit name v1 v2
axis L W L W
0 another ref psi name1 NaN NaN NaN 127
1 ref1 psi name1 51757 46504 403 NaN
2 ref1 psi name2 23000 27000 523 217
...这与我的预期相差不远。
那么用 SQL 语言来做这件事有意义吗?因此,我的以下问题是:使用Flask
框架,使用 pandas 进行数据处理有意义吗?还是我应该坚持使用 SQL 语言?