web-dev-qa-db-fra.com

ajouter une colonne à la table SQLAlchemy

J'ai fait un tableau en utilisant SQLAlchemy et j'ai oublié d'ajouter une colonne. Je veux essentiellement faire ceci:

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

Quelle est la syntaxe pour cela? Je ne pouvais pas le trouver dans les documents.

30
Chris

C'est ce que l'on appelle la migration de base de données (SQLAlchemy ne prend pas en charge la migration prête à l'emploi). Vous pouvez envisager d'utiliser sqlalchemy-migrate pour aider dans ce type de situations, ou vous pouvez simplement ALTER TABLE via l'utilitaire de ligne de commande de la base de données que vous avez choisie,

17
Demian Brecht

J'ai le même problème, et l'idée d'utiliser la bibliothèque de migration uniquement pour cette chose triviale me fait
trembler. Quoi qu'il en soit, c'est ma tentative jusqu'à présent:

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', String(100), primary_key=True)
add_column(engine, table_name, column)

Pourtant, je ne sais pas comment insérer primary_key=True dans une requête SQL brute.

24
AlexP

Consultez cette section de la documentation SQLAlchemy: http://docs.sqlalchemy.org/en/latest/core/metadata.html#altering-schemas-through-migrations

Alembic est le dernier logiciel à offrir ce type de fonctionnalité et est fabriqué par le même auteur que SQLAlchemy.

15
Mike

J'ai une base de données appelée "ncaaf.db" construite avec sqlite3 et une table appelée "jeux". Je voudrais donc CD dans le même répertoire sur mon invite de commande Linux et faire

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

et c'est tout ce qu'il faut! Assurez-vous simplement de mettre à jour vos définitions dans votre code sqlalchemy.

6
appleLover

J'ai eu le même problème, j'ai fini par écrire ma propre fonction en SQL brut. Si vous utilisez SQLITE3, cela peut être utile.

Ensuite, si vous ajoutez la colonne à votre définition de classe en même temps, cela semble faire l'affaire.

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()
4
chasmani
from sqlalchemy import create_engine
engine = create_engine('sqlite:///db.sqlite3')

engine.execute('alter table table_name add column column_name String')
1
Roger Hayashi

Continuant simplement la manière simple proposée par chasmani, peu d'amélioration

'''
# 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)
0
LittleEaster