Python Pandas to_sql,如何创建一个带主键的table?
Python Pandas to_sql, how to create a table with a primary key?
我想创建一个 MySQL table with Pandas' to_sql 函数,它有一个主键(通常有一个主键是好的像这样键入 mysql table):
group_export.to_sql(con = db, name = config.table_group_export, if_exists = 'replace', flavor = 'mysql', index = False)
但这会创建一个没有任何主键(甚至没有任何索引)的 table。
文档提到参数 'index_label' 与 'index' 参数结合可用于创建索引,但没有提及任何主键选项。
免责声明:这个答案比实际更实验,但也许值得一提。
我发现 class pandas.io.sql.SQLTable
有命名参数 key
并且如果你给它分配字段的名称然后这个字段成为主键:
不幸的是,您不能只从 DataFrame.to_sql()
函数中传输此参数。要使用它,您应该:
创建pandas.io.SQLDatabase
实例
engine = sa.create_engine('postgresql:///somedb')
pandas_sql = pd.io.sql.pandasSQL_builder(engine, schema=None, flavor=None)
定义类似于 pandas.io.SQLDatabase.to_sql()
的函数,但带有额外的 *kwargs
参数,该参数传递给在其中创建的 pandas.io.SQLTable
对象(我刚刚复制了原始 to_sql()
方法并添加 *kwargs
):
def to_sql_k(self, frame, name, if_exists='fail', index=True,
index_label=None, schema=None, chunksize=None, dtype=None, **kwargs):
if dtype is not None:
from sqlalchemy.types import to_instance, TypeEngine
for col, my_type in dtype.items():
if not isinstance(to_instance(my_type), TypeEngine):
raise ValueError('The type of %s is not a SQLAlchemy '
'type ' % col)
table = pd.io.sql.SQLTable(name, self, frame=frame, index=index,
if_exists=if_exists, index_label=index_label,
schema=schema, dtype=dtype, **kwargs)
table.create()
table.insert(chunksize)
使用您的 SQLDatabase
实例和要保存的数据帧调用此函数
to_sql_k(pandas_sql, df2save, 'tmp',
index=True, index_label='id', keys='id', if_exists='replace')
我们得到类似
的东西
CREATE TABLE public.tmp
(
id bigint NOT NULL DEFAULT nextval('tmp_id_seq'::regclass),
...
)
在数据库中。
PS 您当然可以通过猴子补丁 DataFrame
、io.SQLDatabase
和 io.to_sql()
函数来方便地使用此解决方法。
automap_base
来自 sqlalchemy.ext.automap
(tableNamesDict 是一个只有 Pandas tables 的字典):
metadata = MetaData()
metadata.reflect(db.engine, only=tableNamesDict.values())
Base = automap_base(metadata=metadata)
Base.prepare()
这本来可以完美地工作,除了一个问题,automap 要求 table 有一个主键。好的,没问题,我确定 Pandas to_sql
有办法指示主键...不。这是它变得有点老套的地方:
for df in dfs.keys():
cols = dfs[df].columns
cols = [str(col) for col in cols if 'id' in col.lower()]
schema = pd.io.sql.get_schema(dfs[df],df, con=db.engine, keys=cols)
db.engine.execute('DROP TABLE ' + df + ';')
db.engine.execute(schema)
dfs[df].to_sql(df,con=db.engine, index=False, if_exists='append')
我遍历 DataFrames
的 dict
,获取用于主键的列列表(即包含 id
的列),使用 get_schema
创建空 tables 然后将 DataFrame
附加到 table.
现在您已经有了模型,您可以明确命名它们(即 User = Base.classes.user
)并将其与 session.query
一起使用,或者使用如下内容创建所有 类 的字典:
alchemyClassDict = {}
for t in Base.classes.keys():
alchemyClassDict[t] = Base.classes[t]
并查询:
res = db.session.query(alchemyClassDict['user']).first()
用pandas上传table后添加主键即可。
group_export.to_sql(con=engine, name=example_table, if_exists='replace',
flavor='mysql', index=False)
with engine.connect() as con:
con.execute('ALTER TABLE `example_table` ADD PRIMARY KEY (`ID_column`);')
with engine.connect() as con:
con.execute('ALTER TABLE for_import_ml ADD PRIMARY KEY ("ID");')
for_import_ml
是数据库中的 table 名称。
对 tomp 的回答稍加改动(我会发表评论,但没有足够的声望点数)。
我正在将 PGAdmin 与 Postgres(在 Heroku 上)一起使用来检查它是否有效。
从 pandas 0.15 开始,至少对于某些风格,您可以使用参数 dtype
来定义主键列。您甚至可以通过这种方式激活 AUTOINCREMENT
。对于 sqlite3,这看起来像这样:
import sqlite3
import pandas as pd
df = pd.DataFrame({'MyID': [1, 2, 3], 'Data': [3, 2, 6]})
with sqlite3.connect('foo.db') as con:
df.to_sql('df', con=con, dtype={'MyID': 'INTEGER PRIMARY KEY AUTOINCREMENT'})
我想创建一个 MySQL table with Pandas' to_sql 函数,它有一个主键(通常有一个主键是好的像这样键入 mysql table):
group_export.to_sql(con = db, name = config.table_group_export, if_exists = 'replace', flavor = 'mysql', index = False)
但这会创建一个没有任何主键(甚至没有任何索引)的 table。
文档提到参数 'index_label' 与 'index' 参数结合可用于创建索引,但没有提及任何主键选项。
免责声明:这个答案比实际更实验,但也许值得一提。
我发现 class pandas.io.sql.SQLTable
有命名参数 key
并且如果你给它分配字段的名称然后这个字段成为主键:
不幸的是,您不能只从 DataFrame.to_sql()
函数中传输此参数。要使用它,您应该:
创建
pandas.io.SQLDatabase
实例engine = sa.create_engine('postgresql:///somedb') pandas_sql = pd.io.sql.pandasSQL_builder(engine, schema=None, flavor=None)
定义类似于
pandas.io.SQLDatabase.to_sql()
的函数,但带有额外的*kwargs
参数,该参数传递给在其中创建的pandas.io.SQLTable
对象(我刚刚复制了原始to_sql()
方法并添加*kwargs
):def to_sql_k(self, frame, name, if_exists='fail', index=True, index_label=None, schema=None, chunksize=None, dtype=None, **kwargs): if dtype is not None: from sqlalchemy.types import to_instance, TypeEngine for col, my_type in dtype.items(): if not isinstance(to_instance(my_type), TypeEngine): raise ValueError('The type of %s is not a SQLAlchemy ' 'type ' % col) table = pd.io.sql.SQLTable(name, self, frame=frame, index=index, if_exists=if_exists, index_label=index_label, schema=schema, dtype=dtype, **kwargs) table.create() table.insert(chunksize)
使用您的
SQLDatabase
实例和要保存的数据帧调用此函数to_sql_k(pandas_sql, df2save, 'tmp', index=True, index_label='id', keys='id', if_exists='replace')
我们得到类似
的东西CREATE TABLE public.tmp
(
id bigint NOT NULL DEFAULT nextval('tmp_id_seq'::regclass),
...
)
在数据库中。
PS 您当然可以通过猴子补丁 DataFrame
、io.SQLDatabase
和 io.to_sql()
函数来方便地使用此解决方法。
automap_base
来自 sqlalchemy.ext.automap
(tableNamesDict 是一个只有 Pandas tables 的字典):
metadata = MetaData()
metadata.reflect(db.engine, only=tableNamesDict.values())
Base = automap_base(metadata=metadata)
Base.prepare()
这本来可以完美地工作,除了一个问题,automap 要求 table 有一个主键。好的,没问题,我确定 Pandas to_sql
有办法指示主键...不。这是它变得有点老套的地方:
for df in dfs.keys():
cols = dfs[df].columns
cols = [str(col) for col in cols if 'id' in col.lower()]
schema = pd.io.sql.get_schema(dfs[df],df, con=db.engine, keys=cols)
db.engine.execute('DROP TABLE ' + df + ';')
db.engine.execute(schema)
dfs[df].to_sql(df,con=db.engine, index=False, if_exists='append')
我遍历 DataFrames
的 dict
,获取用于主键的列列表(即包含 id
的列),使用 get_schema
创建空 tables 然后将 DataFrame
附加到 table.
现在您已经有了模型,您可以明确命名它们(即 User = Base.classes.user
)并将其与 session.query
一起使用,或者使用如下内容创建所有 类 的字典:
alchemyClassDict = {}
for t in Base.classes.keys():
alchemyClassDict[t] = Base.classes[t]
并查询:
res = db.session.query(alchemyClassDict['user']).first()
用pandas上传table后添加主键即可。
group_export.to_sql(con=engine, name=example_table, if_exists='replace',
flavor='mysql', index=False)
with engine.connect() as con:
con.execute('ALTER TABLE `example_table` ADD PRIMARY KEY (`ID_column`);')
with engine.connect() as con:
con.execute('ALTER TABLE for_import_ml ADD PRIMARY KEY ("ID");')
for_import_ml
是数据库中的 table 名称。
对 tomp 的回答稍加改动(我会发表评论,但没有足够的声望点数)。
我正在将 PGAdmin 与 Postgres(在 Heroku 上)一起使用来检查它是否有效。
从 pandas 0.15 开始,至少对于某些风格,您可以使用参数 dtype
来定义主键列。您甚至可以通过这种方式激活 AUTOINCREMENT
。对于 sqlite3,这看起来像这样:
import sqlite3
import pandas as pd
df = pd.DataFrame({'MyID': [1, 2, 3], 'Data': [3, 2, 6]})
with sqlite3.connect('foo.db') as con:
df.to_sql('df', con=con, dtype={'MyID': 'INTEGER PRIMARY KEY AUTOINCREMENT'})