简体   繁体   中英

How do I alter two different column headers of a pre-existing database table in sqlalchemy?

I am using sqlalchemy to reflect the columns of a table in a mysql database into a python script. This is a database I have inherited and some of the column headers for the table have spaces in eg "Chromosome Position". A couple of the column headers also are strings which start with a digit eg "1st time". I would like to alters these headers so that spaces are replaced with underscores and there are no digits at the beginning of the column header string eg "1st time" becomes "firsttime". I followed the advice given sqlalchemy - reflecting tables and columns with spaces which partially solved my problem.

from sqlalchemy import create_engine, Column, event, MetaData 
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.schema import Table
from twisted.python import reflect

Base = automap_base()
engine = create_engine('mysql://username:password@localhost/variants_database', echo=False)

#Using a reflection event to access the column attributes
@event.listens_for(Table, "column_reflect")
def reflect_col(inspector, table, column_info):
     column_info['key'] = column_info['name'].replace(' ', '_')

metadata = MetaData()
session = Session(engine)

class Variants(Base):
    __table__ = Table("variants", Base.metadata, autoload=True,      autoload_with=engine)

Base.prepare(engine, reflect=True)   
session = Session(engine)


a = session.query(Variants).filter(Variants.Gene == "AGL").first()
print a.Chromosome_Position

This allows me to return the values in a.Chromosome_Position. Likewise if I change the method reflect_col to:

@event.listens_for(Table, "column_reflect")
def reflect_col(inspector, table, column_info):
     column_info['key'] = column_info['name'].replace('1st time', 'firsttime')

a = session.query(Variants).filter(Variants.Gene == "AGL").first()
print a.firsttime

This also allow me to return the values in a.firsttime. However I am not able to alter both attributes of the column headers at the same time so changing the method to:

@event.listens_for(Table, "column_reflect")
def reflect_col(inspector, table, column_info):
column_info['key'] = column_info['name'].replace(' ', '_')
column_info['key'] = column_info['name'].replace('1st time', 'secondcheck')

will only modify the last call to column_info which in this case is the column '1st time'. So I can return the values of a.firsttime but not a.Chromosome_Position. How do I change both column name features in the same reflection event?

It seems that you are overwriting the first value after the second replacement. I hope chaining the .replace works:

@event.listens_for(Table, "column_reflect")
def reflect_col(inspector, table, column_info):
   column_info['key'] = column_info['name'].replace(' ', '_').replace('1st_time', 'secondcheck')

[EDIT]: You have to also make sure that the changes wouldn't clash.

Because in this example the first change replaces spaces with underscore, you have to adapt the second replacement, as it's already called 1st_time when the second replace is called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM