当前位置: 首页 > 知识库问答 >
问题:

如何从熊猫数据帧在MySQL DB中创建新表

东门翰
2023-03-14

我最近从使用SQLite来满足大部分数据存储和管理需求过渡到使用MySQL。我想我终于安装了正确的库来使用Python3.6,但是现在我在从MySQL数据库中的dataframe创建新表时遇到了问题。

以下是我导入的库:

import pandas as pd
import mysql.connector
from sqlalchemy import create_engine

在我的代码中,我首先从CSV文件创建一个数据帧(这里没有问题)。

def csv_to_df(infile):
    return pd.read_csv(infile)

然后,我使用以下def函数建立到MySQL数据库的连接:

def mysql_connection():
    user = 'root'
    password = 'abc'
    host = '127.0.0.1'
    port = '3306'
    database = 'a001_db'
    engine = create_engine("mysql://{0}:{1}@{2}:{3}/{4}?charset=utf8".format(user, password, host, port, database))
    return engine

最后,我使用熊猫函数“to_sql”在MySQL数据库中创建数据库表:

def df_to_mysql(df, db_tbl_name, conn=mysql_connection(), index=False):
    df.to_sql(con = conn, name = db_tbl_name, if_exists='replace', index = False)

我使用以下行运行代码:

df_to_mysql(csv_to_df(r'path/to/file.csv'), 'new_database_table')

产生以下误差:

InvalidRequestError: Could not reflect: requested table(s) not available in Engine(mysql://root:***@127.0.0.1:3306/a001_db?charset=utf8): (new_database_table)

我认为这告诉我,在将数据框中的数据传递给这个表之前,我必须首先在数据库中创建一个表,但我对此不是100%肯定。不管怎样,我正在寻找一种在MySQL数据库中创建表的方法,而无需首先手动创建表(我有许多CSV,每个有50个字段,必须作为新表上传到MySQL数据库中)。

有什么建议吗?

共有2个答案

徐德海
2023-03-14

connection = engine.connect()
df.to_sql(con=connection, name='TBL_NAME', schema='SCHEMA', index=False, if_exists='replace')

在特定的模式中使用oracle DB不会出错,但如果权限有限,则不会工作。请注意,表名具有大小写感觉。

长孙波鸿
2023-03-14

我采用了上面aws_学徒建议的方法,首先创建表,然后将数据写入表中。

下面的代码首先从df(自动定义表名和数据类型)自动生成一个mysql表,然后将df数据写入该表。

有几个问题我必须克服,比如:未命名的csv列,为mysql表中的每个字段确定正确的数据类型。

我肯定还有很多其他的(更好?)方法做到这一点,但这似乎行得通。

import pandas as pd
from sqlalchemy import create_engine

infile = r'path/to/file.csv'
db = 'a001_db'
db_tbl_name = 'a001_rd004_db004'

'''
Load a csv file into a dataframe; if csv does not have headers, use the headers arg to create a list of headers; rename unnamed columns to conform to mysql column requirements
'''
def csv_to_df(infile, headers = []):
    if len(headers) == 0:
        df = pd.read_csv(infile)
    else:
        df = pd.read_csv(infile, header = None)
        df.columns = headers
    for r in range(10):
        try:
            df.rename( columns={'Unnamed: {0}'.format(r):'Unnamed{0}'.format(r)},    inplace=True )
        except:
            pass
    return df

'''
Create a mapping of df dtypes to mysql data types (not perfect, but close enough)
'''
def dtype_mapping():
    return {'object' : 'TEXT',
        'int64' : 'INT',
        'float64' : 'FLOAT',
        'datetime64' : 'DATETIME',
        'bool' : 'TINYINT',
        'category' : 'TEXT',
        'timedelta[ns]' : 'TEXT'}
'''
Create a sqlalchemy engine
'''
def mysql_engine(user = 'root', password = 'abc', host = '127.0.0.1', port = '3306', database = 'a001_db'):
    engine = create_engine("mysql://{0}:{1}@{2}:{3}/{4}?charset=utf8".format(user, password, host, port, database))
    return engine

'''
Create a mysql connection from sqlalchemy engine
'''
def mysql_conn(engine):
    conn = engine.raw_connection()
    return conn
'''
Create sql input for table names and types
'''
def gen_tbl_cols_sql(df):
    dmap = dtype_mapping()
    sql = "pi_db_uid INT AUTO_INCREMENT PRIMARY KEY"
    df1 = df.rename(columns = {"" : "nocolname"})
    hdrs = df1.dtypes.index
    hdrs_list = [(hdr, str(df1[hdr].dtype)) for hdr in hdrs]
    for i, hl in enumerate(hdrs_list):
        sql += " ,{0} {1}".format(hl[0], dmap[hl[1]])
    return sql

'''
Create a mysql table from a df
'''
def create_mysql_tbl_schema(df, conn, db, tbl_name):
    tbl_cols_sql = gen_tbl_cols_sql(df)
    sql = "USE {0}; CREATE TABLE {1} ({2})".format(db, tbl_name, tbl_cols_sql)
    cur = conn.cursor()
    cur.execute(sql)
    cur.close()
    conn.commit()

'''
Write df data to newly create mysql table
'''
def df_to_mysql(df, engine, tbl_name):
    df.to_sql(tbl_name, engine, if_exists='replace')

df = csv_to_df(infile)
create_mysql_tbl_schema(df, mysql_conn(mysql_engine()), db, db_tbl_name)
df_to_mysql(df, mysql_engine(), db_tbl_name)
 类似资料:
  • 我有一本字典的形式: 例如, 我想转换成熊猫数据帧与列1的用户名和其他列的电影评级,即: 但是,一些用户没有对电影进行评分,因此这些电影不包括在该用户键()的值()中。在这种情况下,只需用NaN填充条目就好了。 现在,我迭代键,填充列表,然后使用此列表创建数据帧: 但这只给了我一个用户的数据框,这些用户对片场中的所有电影都进行了评分。 我的目标是通过迭代电影标签(而不是上面显示的暴力方法)来追加到

  • 我正在尝试制作一个数据帧,以便可以轻松地将其发送到CSV,否则我必须手动执行此过程。。 我希望这是我的最终输出。每个人都有一个月和年的组合,从2014年1月1日开始,一直到2016年1月12日: 到目前为止的代码: 当我尝试循环创建数据帧时,它要么不工作,要么出现索引错误(因为不匹配列表),我不知所措。 我已经做了一点很好的搜索,并找到了以下一些类似的链接,但我不能反向工程的工作,以适应我的情况。

  • 拿着字典: 我如何把这个字典变成一个数据框,其中的值是列?即。我想要一个数据框显示: 这种形式似乎根本得不到! 谢谢 这是一个不同的问题,另一个问题只是问如何将字典的值放入数据帧,我问的是如何获得我概述的特定形式

  • 我正在使用谷歌云视频智能API,我正在尝试将结果放入一个数据框中。API的输出类是repeatedcompositecontainer。因此,我的想法是在API函数中使用的for循环中构建一个数据帧。 以下是API函数处理结果的方式: 在这篇Stack Overflow文章的帮助下,我创建了一个空列表,并将结果附加到后面的数据框中,如下所示: 当我只尝试最后一个for循环时,它给了我一个很好的结构

  • 我有两个熊猫数据框 步骤2:对于flag=1的行,AA_new将计算为var1(来自df2)*组“A”和val“AA”的df1的'cal1'值*组“A”和val“AA”的df1的'cal2'值,类似地,AB_new将计算为var1(来自df2)*组“A”和val“AB”的df1的'cal1'值*组“A”和val“AB”的df1的'cal2'值 我的预期输出如下所示: 以下基于其他stackflow

  • 假设熊猫数据帧如下所示: 如何将第三行(如row3)提取为pd数据帧?换句话说,row3.shape应该是(1,5),row3.head()应该是: