将列添加到SQLAlchemy表

时间:2011-09-04 17:32:44

标签: python terminal sqlalchemy

我使用SQLAlchemy创建了一个表,忘了添加一个列。我基本上想要这样做:

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

这是什么语法?我在文档中找不到它。

11 个答案:

答案 0 :(得分:20)

我遇到了同样的问题,并且只考虑使用迁移库这个微不足道的事情让我感到高兴 颤抖。无论如何,这是我到目前为止的尝试:

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)

但是,我不知道如何将primary_key=True插入到原始SQL请求中。

答案 1 :(得分:18)

这称为数据库迁移(SQLAlchemy不支持开箱即用的迁移)。您可以使用sqlalchemy-migrate来帮助解决这些问题,或者只需ALTER TABLE通过所选数据库的命令行实用程序,

答案 2 :(得分:15)

请参阅SQLAlchemy文档的此部分:http://docs.sqlalchemy.org/en/latest/core/metadata.html#altering-schemas-through-migrations

Alembic是提供此类功能的最新软件,由与SQLAlchemy相同的作者制作。

答案 3 :(得分:6)

我有一个名为“ncaaf.db”的数据库,用sqlite3和一个名为“games”的表构建。所以我将CD放入我的linux命令提示符下的同一目录并执行

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

这就是全部!只需确保在sqlalchemy代码中更新定义。

答案 4 :(得分:4)

我有同样的问题,我最后只是在原始sql中编写自己的函数。如果您使用的是SQLITE3,这可能很有用。

然后,如果您同时将列添加到类定义中,它似乎就可以了。

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()

答案 5 :(得分:0)

只继续chasmani提出的简单方法,几乎​​没有改善

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

“手动”添加列(不使用python或SQLAlchemy)也许是最简单的?

答案 8 :(得分:0)

我最近遇到了同样的问题,所以我在较早的回答中从 AlexP 那里得到了一个观点。问题在于将新列放入我的程序的元数据中。使用 sqlAlchemy 的 append_column 功能会产生一些意想不到的下游效果('str' 对象没有属性 'dialect impl')。我通过添加带有 DDL(在本例中为 MySQL 数据库)的列,然后将表从数据库反射回我的元数据中来纠正此问题。

代码大致如下(对我所拥有的略有修改,以将其减少到最低限度的本质。对于任何错误,我深表歉意 - 如果有,它们应该是轻微的)...

try:
    # Use back quotes as a protection against SQL Injection Attacks. Can we do more?
    common.qry_engine.execute('ALTER TABLE %s ADD COLUMN %s %s' %
                              ('`' + self.tbl.schema + '`.`' + self.tbl.name + '`',
                               '`' + self.outputs[new_col] + '`', 'VARCHAR(50)'))
except exc.SQLAlchemyError as msg:
    raise GRError(desc='Unable to physically add derived column to table. Contact support.',
                  data=str(self.outputs), other_info=str(msg))

try:    # Refresh the metadata to show the new column
    self.tbl = sqlalchemy.Table(self.tbl.name, self.tbl.metadata, extend_existing=True, autoload=True)
except exc.SQLAlchemyError as msg:
    raise GRError(desc='Unable to establish metadata for new column. Contact support.',
                  data=str(self.outputs), other_info=str(msg))

答案 9 :(得分:0)

是的,你可以 安装 sqlalchemy-migrate (pip install sqlalchemy-migrate) 并在脚本中使用它来调用 Table 和 Column create() 方法:

from sqlalchemy import String, MetaData, create_engine
from migrate.versioning.schema import Table, Column

db_engine =  create_engine(app.config.get('SQLALCHEMY_DATABASE_URI'))
db_meta = MetaData(bind=db_engine)

table = Table('tabel_name' , db_meta)
col = Column('new_column_name', String(20), default='foo')
    col.create(table)

答案 10 :(得分:-1)

这里的问题相同。我要做的是遍历数据库并使用额外列将每个条目添加到新数据库,然后删除旧数据库并将新数据重命名为此数据库。