add column to SQLAlchemy Table

Posted on

Question :

add column to SQLAlchemy Table

I made a table using SQLAlchemy and forgot to add a column. I basically want to do this:

users.addColumn('user_id', ForeignKey('users.user_id'))

What’s the syntax for this? I couldn’t find it in the docs.

Asked By: Chris

||

Answer #1:

This is referred to as database migration (SQLAlchemy doesn’t support migration out of the box). You can look at using sqlalchemy-migrate to help in these kinds of situations, or you can just ALTER TABLE through your chosen database’s command line utility,

Answered By: Demian Brecht

Answer #2:

I have the same problem, and a thought of using migration library only for this trivial thing makes me
tremble. Anyway, this is my attempt so far:

def add_column(engine, table_name, column):
    column_name = column.compile(dialect=engine.dialect)
    column_type = column.type.compile(engine.dialect)
    engine.execute('ALTER TABLE %s ADD COLUMN %s %s' % (table_name, column_name, column_type))

column = Column('new_column_name', String(100), primary_key=True)
add_column(engine, table_name, column)

Still, I don’t know how to insert primary_key=True into raw SQL request.

Answered By: AlexP

Answer #3:

See this section of the SQLAlchemy documentation: http://docs.sqlalchemy.org/en/latest/core/metadata.html#altering-schemas-through-migrations

Alembic is the latest software to offer this type of functionality and is made by the same author as SQLAlchemy.

Answered By: Mike

Answer #4:

I have a database called “ncaaf.db” built with sqlite3 and a table called “games”. So I would CD into the same directory on my linux command prompt and do

sqlite3 ncaaf.db
alter table games add column q4 type float

and that is all it takes! Just make sure you update your definitions in your sqlalchemy code.

Answered By: appleLover

Answer #5:

I had the same problem, I ended up just writing my own function in raw sql. If you are using SQLITE3 this might be useful.

Then if you add the column to your class definition at the same time it seems to do the trick.

import sqlite3 

def add_column(database_name, table_name, column_name, data_type):

  connection = sqlite3.connect(database_name)
  cursor = connection.cursor()

  if data_type == "Integer":
    data_type_formatted = "INTEGER"
  elif data_type == "String":
    data_type_formatted = "VARCHAR(100)"

  base_command = ("ALTER TABLE '{table_name}' ADD column '{column_name}' '{data_type}'")
  sql_command = base_command.format(table_name=table_name, column_name=column_name, data_type=data_type_formatted)

  cursor.execute(sql_command)
  connection.commit()
  connection.close()
Answered By: chasmani

Answer #6:

from sqlalchemy import create_engine
engine = create_engine('sqlite:///db.sqlite3')

engine.execute('alter table table_name add column column_name String')
Answered By: Roger Hayashi

Answer #7:

Just continuing the simple way proposed by chasmani, little improvement

'''
# simple migration
# columns to add: 
# last_status_change = Column(BigInteger, default=None) 
# last_complete_phase = Column(String, default=None)  
# complete_percentage = Column(DECIMAL, default=0.0)
'''

import sqlite3

from config import APP_STATUS_DB
from sqlalchemy import types


def add_column(database_name: str, table_name: str, column_name: str, data_type: types, default=None):
    ret = False

    if default is not None:
        try:
            float(default)
            ddl = ("ALTER TABLE '{table_name}' ADD column '{column_name}' '{data_type}' DEFAULT {default}")
        except:
            ddl = ("ALTER TABLE '{table_name}' ADD column '{column_name}' '{data_type}' DEFAULT '{default}'")
    else:
        ddl = ("ALTER TABLE '{table_name}' ADD column '{column_name}' '{data_type}'")

    sql_command = ddl.format(table_name=table_name, column_name=column_name, data_type=data_type.__name__,
                             default=default)
    try:
        connection = sqlite3.connect(database_name)
        cursor = connection.cursor()
        cursor.execute(sql_command)
        connection.commit()
        connection.close()
        ret = True
    except Exception as e:
        print(e)
        ret = False
    return ret


add_column(APP_STATUS_DB, 'procedures', 'last_status_change', types.BigInteger)
add_column(APP_STATUS_DB, 'procedures', 'last_complete_phase', types.String)
add_column(APP_STATUS_DB, 'procedures', 'complete_percentage', types.DECIMAL, 0.0)
Answered By: LittleEaster

Answer #8:

Adding the column “manually” (not using python or SQLAlchemy) is perhaps the easiest?

Leave a Reply

Your email address will not be published. Required fields are marked *