Pandas to_sql change le type de colonne de varchar en text

J'ai écrit un petit script pour copyr une table entre les servers SQL. Cela fonctionne, mais l'une des colonnes a changé le type de varchar en text … Comment est-ce que je fais pour copyr une table avec les mêmes types de colonnes?

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_ssortingng='mssql+pymssql://{}:{}@{}/{}'.format(db_user,db_password,db_server,db_database) engine=create_engine(connection_ssortingng) data.to_sql(name="some_table",con=engine,if_exists='replace',index=False) if __name__ == "__main__": main() 

Merci

Considérons trois approches:

SPECIFIER LES TYPES (proactif comme anticiper à l'avance)

En utilisant l'argument dtype de pandas.DataFrame.to_sql , passez un dictionary de types sqlalchemy pour les colonnes nommées.

 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} 

SUPPRIMER LES DONNÉES (proactive comme anticipée)

Nettoyer la table avec la requête d'action DELETE . Ensuite, migrez uniquement datatables de pandas vers SQL Server sans modifier structurellement la table puisque l'argument to_sql replace recrée la table. Cette approche suppose que datatables sont toujours cohérentes (pas de nouvelles colonnes / types modifiés) avec la table de database.

 def main(): connection_ssortingng = 'mssql+pymssql://{}:{}@{}/{}'\ .format(db_user,db_password,db_server,db_database) engine = create_engine(connection_ssortingng) # 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) 

MODIFIER LA COLONNE (réactif car il corrige ad-hoc)

Modifiez la colonne après la migration avec une instruction SQL DDL.

 def main(): connection_ssortingng = 'mssql+pymssql://{}:{}@{}/{}'\ .format(db_user,db_password,db_server,db_database) engine = create_engine(connection_ssortingng) # 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);") 

Je recommand la deuxième approche car je crois que les bases de données devraient être agnostiques au code d'application comme python et pandas. Par conséquent, la construction initiale / reconstruction du schéma de table devrait être un process planifié et manuel, et aucun script ne devrait modifier structurellement une database à la volée, interagir seulement avec datatables.