【问题标题】:python-pandas and databases like mysqlpython-pandas 和 mysql 等数据库
【发布时间】:2020-03-06 17:07:45
【问题描述】:

Pandas 的文档中有大量关于处理以各种格式存储的数据的最佳实践示例。

但是,我找不到任何使用 MySQL 等数据库的好的示例。

谁能指出我的链接或提供一些代码 sn-ps 如何使用 mysql-python 有效地将查询结果转换为 Pandas 中的数据帧?

【问题讨论】:

标签: python pandas


【解决方案1】:

正如 Wes 所说,一旦您使用 DBI 兼容库获得数据库连接,io/sql 的 read_sql 就会执行此操作。我们可以看两个使用MySQLdbcx_Oracle 库连接到Oracle 和MySQL 并查询它们的数据字典的简短示例。这是cx_Oracle 的示例:

import pandas as pd
import cx_Oracle

ora_conn = cx_Oracle.connect('your_connection_string')
df_ora = pd.read_sql('select * from user_objects', con=ora_conn)    
print 'loaded dataframe from Oracle. # Records: ', len(df_ora)
ora_conn.close()

这是MySQLdb 的等效示例:

import MySQLdb
mysql_cn= MySQLdb.connect(host='myhost', 
                port=3306,user='myusername', passwd='mypassword', 
                db='information_schema')
df_mysql = pd.read_sql('select * from VIEWS;', con=mysql_cn)    
print 'loaded dataframe from MySQL. records:', len(df_mysql)
mysql_cn.close()

【讨论】:

    【解决方案2】:

    对于这个问题的近期读者:pandas 在他们的docs for version 14.0 中有以下警告:

    警告:一些现有函数或函数别名已被 已弃用,将在未来的版本中删除。这包括: tquery、uquery、read_frame、frame_query、write_frame。

    还有:

    警告:使用 DBAPI 连接对象时对“mysql”风格的支持已 已弃用。 SQLAlchemy 将进一步支持 MySQL 发动机 (GH6900)。

    这使得这里的许多答案都过时了。你应该使用sqlalchemy:

    from sqlalchemy import create_engine
    import pandas as pd
    engine = create_engine('dialect://user:pass@host:port/schema', echo=False)
    f = pd.read_sql_query('SELECT * FROM mytable', engine, index_col = 'ID')
    

    【讨论】:

    • 加载一个包含 133 行 7 列的表大约需要 30 秒。您能提供一些关于为什么会这样的见解吗?
    • @idoda [一般来说,这不是问题的主题,最好提出一个新问题,以便获得更多意见]。你确定这不是请求延迟的问题吗?只是发送查询和检索结果明显更快吗?
    • @Korem 我确实考虑过开设一个新的,但我想首先确保它不是一个微不足道的。当我使用 mySql 客户端(Sequel pro)并查询数据库时,reuslts 出现得更快。当您说“简单地发送然后检索”时,您的意思是这样吗? (使用客户端)
    • @idoda 我的意思是将执行engine.execute("select * FROM mytable") 所需的时间与执行pd.read_sql_query('SELECT * FROM mytable', engine) 所需的时间进行比较
    • 可以将 sqlalchemy 查询(如我下面的答案中的 session.query)直接传递给 pandas 方法吗?那将是一个开膛手!
    【解决方案3】:

    为了记录,这里是一个使用 sqlite 数据库的例子:

    import pandas as pd
    import sqlite3
    
    with sqlite3.connect("whatever.sqlite") as con:
        sql = "SELECT * FROM table_name"
        df = pd.read_sql_query(sql, con)
        print df.shape
    

    【讨论】:

    • 您可以通过在frame_query 中指定index_col='timestamp' 来指定要用作索引的列。
    【解决方案4】:

    我更喜欢使用SQLAlchemy 创建查询,然后从中创建一个DataFrame。如果您打算反复混合和匹配事物,SQLAlchemy 可以更轻松地以 Python 方式组合 SQL 条件。

    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Table
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    from pandas import DataFrame
    import datetime
    
    # We are connecting to an existing service
    engine = create_engine('dialect://user:pwd@host:port/db', echo=False)
    Session = sessionmaker(bind=engine)
    session = Session()
    Base = declarative_base()
    
    # And we want to query an existing table
    tablename = Table('tablename', 
        Base.metadata, 
        autoload=True, 
        autoload_with=engine, 
        schema='ownername')
    
    # These are the "Where" parameters, but I could as easily 
    # create joins and limit results
    us = tablename.c.country_code.in_(['US','MX'])
    dc = tablename.c.locn_name.like('%DC%')
    dt = tablename.c.arr_date >= datetime.date.today() # Give me convenience or...
    
    q = session.query(tablename).\
                filter(us & dc & dt) # That's where the magic happens!!!
    
    def querydb(query):
        """
        Function to execute query and return DataFrame.
        """
        df = DataFrame(query.all());
        df.columns = [x['name'] for x in query.column_descriptions]
        return df
    
    querydb(q)
    

    【讨论】:

    【解决方案5】:

    MySQL 示例:

    import MySQLdb as db
    from pandas import DataFrame
    from pandas.io.sql import frame_query
    
    database = db.connect('localhost','username','password','database')
    data     = frame_query("SELECT * FROM data", database)
    

    【讨论】:

    • frame_query 现在已弃用。现在改用pd.read_sql(query, db)
    【解决方案6】:

    同样的语法也适用于使用 podbc 的 Ms SQL 服务器。

    import pyodbc
    import pandas.io.sql as psql
    
    cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=servername;DATABASE=mydb;UID=username;PWD=password') 
    cursor = cnxn.cursor()
    sql = ("""select * from mytable""")
    
    df = psql.frame_query(sql, cnxn)
    cnxn.close()
    

    【讨论】:

      【解决方案7】:

      这就是您使用 psycopg2 驱动程序连接到 PostgreSQL 的方式(如果您使用的是 Debian Linux 衍生操作系统,请使用“apt-get install python-psycopg2”安装)。

      import pandas.io.sql as psql
      import psycopg2
      
      conn = psycopg2.connect("dbname='datawarehouse' user='user1' host='localhost' password='uberdba'")
      
      q = """select month_idx, sum(payment) from bi_some_table"""
      
      df3 = psql.frame_query(q, conn)
      

      【讨论】:

        【解决方案8】:

        对于 Sybase,以下工作(使用 http://python-sybase.sourceforge.net

        import pandas.io.sql as psql
        import Sybase
        
        df = psql.frame_query("<Query>", con=Sybase.connect("<dsn>", "<user>", "<pwd>"))
        

        【讨论】:

          【解决方案9】:

          pandas.io.sql.frame_query 已弃用。请改用pandas.read_sql

          【讨论】:

            【解决方案10】:

            导入模块

            import pandas as pd
            import oursql
            

            连接

            conn=oursql.connect(host="localhost",user="me",passwd="mypassword",db="classicmodels")
            sql="Select customerName, city,country from customers order by customerName,country,city"
            df_mysql = pd.read_sql(sql,conn)
            print df_mysql
            

            使用 pandas.io.sql frame_works(带有弃用警告)效果很好。使用的数据库是mysql教程中的示例数据库。

            【讨论】:

              【解决方案11】:

              这应该可以正常工作。

              import MySQLdb as mdb
              import pandas as pd
              con = mdb.connect(‘127.0.0.1’, ‘root’, ‘password’, ‘database_name’);
              with con:
               cur = con.cursor()
               cur.execute(“select random_number_one, random_number_two, random_number_three from randomness.a_random_table”)
               rows = cur.fetchall()
               df = pd.DataFrame( [[ij for ij in i] for i in rows] )
               df.rename(columns={0: ‘Random Number One’, 1: ‘Random Number Two’, 2: ‘Random Number Three’}, inplace=True);
               print(df.head(20))
              

              【讨论】:

                【解决方案12】:

                这有助于我从基于 python 3.xlambda 函数 连接到 AWS MYSQL(RDS) > 并加载到 pandas 数据帧中

                import json
                import boto3
                import pymysql
                import pandas as pd
                user = 'username'
                password = 'XXXXXXX'
                client = boto3.client('rds')
                def lambda_handler(event, context):
                    conn = pymysql.connect(host='xxx.xxxxus-west-2.rds.amazonaws.com', port=3306, user=user, passwd=password, db='database name', connect_timeout=5)
                    df= pd.read_sql('select * from TableName limit 10',con=conn)
                    print(df)
                    # TODO implement
                    #return {
                    #    'statusCode': 200,
                    #    'df': df
                    #}
                

                【讨论】:

                  【解决方案13】:

                  对于 Postgres 用户

                  import psycopg2
                  import pandas as pd
                  
                  conn = psycopg2.connect("database='datawarehouse' user='user1' host='localhost' password='uberdba'")
                  
                  customers = 'select * from customers'
                  
                  customers_df = pd.read_sql(customers,conn)
                  
                  customers_df
                  

                  【讨论】:

                  • 您能否指出与@Will 的answer 的区别以及为什么要选择您的解决方案?
                  猜你喜欢
                  • 1970-01-01
                  • 2014-03-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-03-02
                  • 2013-07-22
                  • 1970-01-01
                  • 2020-10-19
                  • 2020-11-06
                  相关资源
                  最近更新 更多