AZh*_*hao 6 python sqlalchemy pandas
在将数据查询到pandas数据帧时,有没有办法保留SqlAlchemy属性名称?
这是我的数据库的简单映射.对于学校表,我将"学校名称"的"SchoolDistrict"重命名为更短的"地区".我从DBA中删除了几个层,因此在源代码中更改它们是不可行的.
class School(Base):
__tablename__ = 'DimSchool'
id = Column('SchoolKey', Integer, primary_key=True)
name = Column('SchoolName', String)
district = Column('SchoolDistrict', String)
class StudentScore(Base):
__tablename__ = 'FactStudentScore'
SchoolKey = Column('SchoolKey', Integer, ForeignKey('DimSchool.SchoolKey'), primary_key = True)
PointsPossible = Column('PointsPossible', Integer)
PointsReceived = Column('PointsReceived', Integer)
school = relationship("School", backref='studentscore')
Run Code Online (Sandbox Code Playgroud)
所以当我查询类似的东西:
query = session.query(StudentScore, School).join(School)
df = pd.read_sql(query.statement, query.session.bind)
Run Code Online (Sandbox Code Playgroud)
我在返回的DataFrame df中得到了列的基础'SchoolDistrict'名称,而不是我的属性名称.
编辑:更令人讨厌的情况是表格中存在重复的列名称.例如:
class Teacher(Base):
__tablename__ = 'DimTeacher'
id = Column('TeacherKey', Integer, primary_key=True)
fname = Column('FirstName', String)
lname = Column('FirstName', String)
class Student(Base):
__tablename__ = 'DimStudent'
id = Column('StudentKey', Integer, primary_key=True)
fname = Column('FirstName', String)
lname = Column('FirstName', String)
Run Code Online (Sandbox Code Playgroud)
因此,跨两个表的查询(如下所示)会生成具有重复的FirstName和LastName列的数据帧.
query = session.query(StudentScore, Student, Teacher).join(Student).join(Teacher)
Run Code Online (Sandbox Code Playgroud)
是否可以在查询时重命名这些列?现在我无法用这两个列名系统保持头脑清醒.
如果我事后必须维护代码,我会强烈抱怨这种解决方案。但你的问题有太多限制,我找不到更好的。
\n\n首先,您使用像这样的内省构造一个具有等效模式和类列的字典(我正在使用您发布的第一个示例):
\n\nIn [132]:\n\ndef add_to_dict(c_map, t_map, table):\n name = table.__tablename__\n t_map[name] = table.__name__\n #print name\n c_map[name] = {}\n for column in dir(table):\n c_schema_name = table.__mapper__.columns.get(column)\n if isinstance(c_schema_name, Column):\n #print column, c_schema_name.name\n c_map[name][c_schema_name.name] = column\n\nc_map = {}\nt_map = {}\nadd_to_dict(c_map, t_map, School)\nadd_to_dict(c_map, t_map, StudentScore)\nprint c_map[\'DimSchool\'][\'SchoolKey\']\nprint c_map[\'FactStudentScore\'][\'SchoolKey\']\nprint t_map[\'DimSchool\']\nid\nSchoolKey\nSchool\nRun Code Online (Sandbox Code Playgroud)\n\n[编辑:关于通过内省构建字典的方式的澄清
\n\nsqlalchemy 映射器获取数据库列名称Column仅当属性确实是列时,Column对象,将它们添加到列名字典中。数据库名称是通过以下方式获取的.name,另一个只是属性创建数据库中的所有对象后仅运行一次,每个表类调用一次。]
\n\n然后,您使用 sql 语句并构建您将获得的列的翻译列表:
\n\nIn [134]:\n\ndf_columns = []\nfor column in str(query.statement).split(\'FROM\')[0].split(\'SELECT\')[1].split(\',\'):\n table = column.split(\'.\')[0].replace(\'"\', \'\').strip()\n c_schema = column.split(\'.\')[1].replace(\'"\', \'\').strip()\n df_columns += [t_map[table] + \'.\' + eq[table][c_schema]]\nprint df_columns\n\xe2\x80\x8b\n[\'StudentScore.SchoolKey\', \'StudentScore.PointsPossible\', \'StudentScore.PointsReceived\', \'School.id\', \'School.name\', \'School.district\']\nRun Code Online (Sandbox Code Playgroud)\n\n最后,您按照问题中的方式读取数据框并更改列的名称:
\n\nIn [137]:\n\ndf.columns = df_columns\nIn [138]:\n\ndf\nOut[138]:\nStudentScore.SchoolKey StudentScore.PointsPossible StudentScore.PointsReceived School.id School.name School.district\n0 1 1 None 1 School1 None\nRun Code Online (Sandbox Code Playgroud)\n\n(数据只是我创建的一个愚蠢的寄存器)。
\n\n希望能帮助到你!
\n| 归档时间: |
|
| 查看次数: |
2476 次 |
| 最近记录: |