2015-10-23 43 views
3

我试图建立一个表时SQLAlchemy的,至于现在的列中出现的字母顺序设置列的顺序,我现在有:设置排序

def data_frame(query, columns): 
    def make_row(x): 
     return dict([(c, getattr(x, c)) for c in columns]) 
    return pd.DataFrame([make_row(x) for x in query]) 

PackL = create_engine('mssql+pyodbc://u:[email protected]/db1?driver=SQL Server', echo=False) 
Fabr = create_engine('mssql+pyodbc://u:[email protected]/db2?driver=SQL Server', echo=False) 
Session = sessionmaker(bind=PackL) 
session = Session() 
Base = declarative_base() 
metadata = MetaData() 

class Tranv(Base): 
    __tablename__= "Transactions" 
    __table_args__= {'autoload': True, 'autoload_with':PackL} 

newvarv = session.query(Tranv).filter_by(status='SCRAP').filter(Tranv.time_stamp. 
between('2015-10-01', '2015-10-09')) 

session.close() 

dfx = data_frame(newvarv, ['action', 'employee_number', 'time_stamp', 'qty', 
'part_number', 'card_number']) 

当前dfx具有按字母顺序排列的列,但我希望它按照我在创建数据框dfx时定义列的顺序对它们排序。因此,订单可以是行动,员工编号,时间戳,数量,零件编号,卡号。我可以很容易地用熊猫做到这一点,但这似乎是额外的(和不必要的)步骤。

我搜索了文档,谷歌,& stackoverflow但没有什么真的似乎符合我的需求。由于我还是SQLAlchemy的新手,我很感激任何帮助。我的想法是,因为我自动加载表格,我无法轻松定义列的顺序(我确定有一种解决方法,但没有线索在可能找到的文档中的位置) ?

+1

我想你也可以使用'dfx = pd.read_sql_query(newvarv,PackL)'将查询转换为数据框而不是编写自己的方法(但不完全确定)。 – joris

+1

要对我自己的评论发表评论,您需要传递'newvarv.selectable',查看我的更新回答 – joris

回答

2

你的列不按你指定的顺序排列的原因与sql查询或sqlalchemy无关。这是因为您将查询输出转换为字典,然后将其输入到DataFrame
由于python中的字典没有顺序,熊猫将按字母顺序对其进行排序以获得可预测的输出。

使用dict目前的做法,你可以随时通过做dfx.reindex(columns=['action', ..., 'card_number'])


除了解释更改列的顺序之后,为什么它不在你的情况下令,有可能更好的方法解决这个问题:

  • 使用内建pd.read_sql_query。当会话和查询对象时,你可以在selectable属性传递给read_sql_query将其转换为一个数据帧:

    query = session.query(Table)... 
    df = pd.read_sql_query(query.selectable, engine) 
    
  • 没有转换为一个字典,但保持输出作为你喂到DataFrame元组:此将保持查询输出的顺序。
+0

谢谢您的理解;没有考虑查询输出转换。我已经尝试过pd.read_sql_query(事实上,我拿出了我的data_frame函数并用你之前的评论替换了它),但我总是得到这个错误:sqlalchemy.exc.InvalidRequestError:不可执行的对象类型: grlaer

+1

是的,很抱歉,您是正确的。但是,您可以传递Query对象的'selectable'属性:'pd.read_sql_query(query.selectable,engine)'。这样,您不需要自己的书面方法将其转换为数据框。 – joris

+0

谢谢,这可能是最简单的解决方案,而且比我之前做的更平易近人。 – grlaer