簡體   English   中英

Python Pandas to_sql,如何創建帶有主鍵的表?

[英]Python Pandas to_sql, how to create a table with a primary key?

我想用 Pandas 的 to_sql 函數創建一個 MySQL 表,它有一個主鍵(在 mysql 表中有一個主鍵通常很好),如下所示:

group_export.to_sql(con = db, name = config.table_group_export, if_exists = 'replace', flavor = 'mysql', index = False)

但這會創建一個沒有任何主鍵(甚至沒有任何索引)的表。

該文檔提到參數“index_label”與“index”參數結合可用於創建索引,但沒有提及主鍵的任何選項。

文檔

上傳帶有pandas的表后,只需添加主鍵即可。

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`);')

免責聲明:這個答案更具實驗性而不是實用,但也許值得一提。

我發現類pandas.io.sql.SQLTable已命名參數key ,如果您為其分配字段名稱,則該字段將成為主鍵:

不幸的是,您不能只從DataFrame.to_sql()函數傳輸這個參數。 要使用它,您應該:

  1. 創建pandas.io.SQLDatabase實例

    engine = sa.create_engine('postgresql:///somedb') pandas_sql = pd.io.sql.pandasSQL_builder(engine, schema=None, flavor=None)
  2. 定義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)
  3. 使用您的SQLDatabase實例和要保存的數據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 您當然可以使用猴子補丁DataFrameio.SQLDatabaseio.to_sql()函數來方便地使用此解決方法。

automap_basesqlalchemy.ext.automap (tableNamesDict僅與熊貓表的字典):

metadata = MetaData()
metadata.reflect(db.engine, only=tableNamesDict.values())
Base = automap_base(metadata=metadata)
Base.prepare()

這本來可以完美運行,除了一個問題, automap 要求表具有主鍵 好的,沒問題,我確定 Pandas to_sql有一種方法來指示主鍵......不。 這是它變得有點hacky的地方:

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')

我遍歷DataFramesdict ,獲取用於主鍵的列列表(即那些包含id ),使用get_schema創建空表,然后將DataFrame附加到表中。

現在你有了模型,你可以顯式地命名和使用它們(即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()
with engine.connect() as con:
    con.execute('ALTER TABLE for_import_ml ADD PRIMARY KEY ("ID");')

for_import_ml是數據庫中的表名。

為 tomp 的答案添加一些細微的變化(我會發表評論,但沒有足夠的聲望點)。

我正在使用帶有 Postgres(在 Heroku 上)的 PGAdmin 來檢查它是否有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM