首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pandas to_sql将列类型从varchar更改为text

Pandas to_sql将列类型从varchar更改为text
EN

Stack Overflow用户
提问于 2017-04-26 18:11:29
回答 1查看 12K关注 0票数 6

我编写了一个小脚本来在SQL服务器之间复制表。它可以工作,但其中一列将类型从varchar更改为text...如何复制具有相同列类型的表?

代码语言:javascript
运行
复制
import pymssql
import pandas as pd
from sqlalchemy import create_engine


db_server= 1.2.3.4\\r2
db_database="Test_DB"
db_user="vaf"
db_password="1234"

local_db_server="1.1.1.1\\r2"
local_db_database="Test_DB"
local_db_user="vaf"
local_db_password="1234"

some_query=("""
select * from some_table
""")




def main():
    conn=pymssql.connect(server=local_db_server,user=local_db_user,password=local_db_password,database=local_db_database,charset='UTF-8')
    data=pd.io.sql.read_sql(some_query,conn)

    connection_string='mssql+pymssql://{}:{}@{}/{}'.format(db_user,db_password,db_server,db_database)
    engine=create_engine(connection_string)
    data.to_sql(name="some_table",con=engine,if_exists='replace',index=False)

if __name__ == "__main__":
    main()

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-26 23:14:25

考虑以下三种方法:

指定类型(主动,因为它预计会提前完成)

使用pandas.DataFrame.to_sql的dtype参数,为指定列传递sqlalchemy types字典。

代码语言:javascript
运行
复制
data.to_sql(name="some_table", con=engine, if_exists='replace', index=False,
            dtype={'datefld': sqlalchemy.DateTime(), 
                   'intfld':  sqlalchemy.types.INTEGER(),
                   'strfld': sqlalchemy.types.VARCHAR(length=255),
                   'floatfld': sqlalchemy.types.Float(precision=3, asdecimal=True),
                   'booleanfld': sqlalchemy.types.Boolean}

删除DATA (主动,因为它提前预料到了)

使用DELETE操作查询清空表格。然后,只将数据从pandas迁移到SQL Server,而不改变表的结构,因为to_sql replace参数会重新创建表。这种方法假设数据帧始终与数据库表一致(没有新的列/更改的类型)。

代码语言:javascript
运行
复制
def main():
   connection_string = 'mssql+pymssql://{}:{}@{}/{}'\
                         .format(db_user,db_password,db_server,db_database)
   engine = create_engine(connection_string)

   # IMPORT DATA INTO DATA FRAME
   data = pd.read_sql(some_query, engine)

   # SQL DELETE (CLEAN OUT TABLE) VIA TRANSACTION
   with engine.begin() as conn:     
      conn.execute("DELETE FROM some_table")

   # MIGRATE DATA INTO DATA FRAME (APPEND NOT REPLACE)
   data.to_sql(name='some_table', con=engine, if_exists='append', index=False)

MODIFY COLUMN (即席修复时的反应性)

使用DDL SQL语句在迁移后更改列。

代码语言:javascript
运行
复制
def main():
   connection_string = 'mssql+pymssql://{}:{}@{}/{}'\
                         .format(db_user,db_password,db_server,db_database)
   engine = create_engine(connection_string)

   # IMPORT DATA INTO DATA FRAME
   data = pd.read_sql(some_query, engine)

   # MIGRATE DATA INTO DATA FRAME 
   data.to_sql(name="some_table", con=engine, if_exists='replace', index=False)

   # ALTER COLUMN TYPE (ASSUMING USER HAS RIGHTS/PRIVILEGES)
   with engine.begin() as conn:     
      conn.execute("ALTER TABLE some_table ALTER COLUMN mytextcolumn VARCHAR(255);")

我推荐第二种方法,因为我认为数据库应该与python和pandas等应用程序代码无关。因此,表模式的初始构建/重新构建应该是一个有计划的、手动的过程,任何脚本都不应该在结构上即时更改数据库,而只与数据交互。

票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43631181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档