愚蠢(但有效)的数据库模式和使用sqlalchemy的数据迁移框架。

sqlalchemygrate的Python项目详细描述


sqlalchemygrate sqlalchemygrate sqlalchemygrate

这是我愚蠢的(但有效的)迁移框架,构建在SQLAlchemy-世界上最好的数据库抽象库之上。grate不做像跟踪模式版本和单步升级/降级路径或测试这样的花哨事情。buuut,您可以使用upgrade命令在它周围创建一个包装器来执行所有这些操作。

有一件事grate在开箱即用时做得很好,那就是从一个sqlalchemy目标引擎到另一个引擎的逐行重复插入。这意味着您可以随意更改sqlalchemy模式,然后要导入数据,您可以创建另一个数据库,并逐行从旧数据集中重新插入到新数据集中。您甚至可以提供转换函数,以便在必要时转换数据。

警告请考虑此测试质量。缺少错误检查,因此可能会引发恶意异常。正在添加更多功能和帮助程序。

使用量

Usage: grate COMMAND [ARGS ...]

Really silly schema migration framework, built for SQLAlchemy.

Commands:
    migrate ENGINE_FROM ENGINE_TO
        Migrate schema or data from one engine to another.

    upgrade ENGINE UPGRADE_FN
        Perform in-place upgrade of a schema in an engine.

Examples:
    grate migrate "mysql://foo:bar@localhost/baz" "sqlite:///:memory:" \
        --metadata model.meta:metadata --verbose

    grate upgrade "mysql://foo:bar@localhost/baz" migration.001_change_fancy_column:upgrade

Hint: The upgrade command can also be used to downgrade, just point it
to the relevant downgrade function. For extra awesomeness, use schema-altering
DDLs provided by sqlalchemy-migrate.


Options:
  -h, --help            show this help message and exit
  -v, --verbose         Enable verbose output. Use twice to enable debug
                        output.
  --show-sql            Echo SQLAlchemy queries.

  migrate:
    --only-tables=TABLES
                        Only perform migration on the given tables. (comma-
                        separated table names)
    --skip-tables=TABLES
                        Skip migration on the given tables. (comma-separated
                        table names)
    --limit=LIMIT       Number to select per insert loop. (default: 100000)
    --metadata=METADATA
                        MetaData object bound to the target schema definition.
                        Example: model.metadata:MetaData
    --convert=FN        (Optional) Convert function to run data through.
                        Example: migration.v1:convert

函数示例

转换

迁移时,您可以提供转换函数以将数据导入。下面是一个人的样子:

# migration/v1.py:

def convert(table, row):
    """
    :param table: SQLAlchemy table schema object.
    :param row: Current row from the given table (immutable, must make a copy to change).

    Returns a dict with column:value mappings.
    """
    if table.name == 'user':
        row = dict(row)
        row['email'] = row['email'].lower()
    elif table.name == 'job':
        row = dict(row)
        del row['useless_column']

    return row

然后我们将这个函数与--convert=migration.v1:convert一起使用。使用这个特性会对性能造成相当明显的损害,即必须通过一个具有自己逻辑的函数来运行每一行,但是对于小数据集来说,这并不太糟糕,也不太方便忽略。

升级

执行升级命令时,可以在不完全重新插入的情况下进行就地更改。对于较大的数据集或较小的模式更改,这是一个更现实的替代方案。

# migration/001_add_fancy_column.py:

from sqlalchemy import *
from migrate import * # sqlalchemy-migrate lets us do dialect-agnostic schema changes

# sqlalchemygrate also provides some helpers just in case
from grate.migrations import table_migrate

def upgrade(metadata):
    """
    :param metadata: SQLAlchemy MetaData bound to an engine and autoreflected.
    """
    fancy_table = metadata.tables['fancy_table']

    # Create column using sqlalchemy-migrate
    col = Column('fancy_column', types.Integer)
    col.create(fancy_table)

    ## Or run some arbitrary SQL
    # metadata.bind.execute(...)

    ## Need to do a row-by-row re-insert? Use the table_migrate helper
    ## We do a migration from one engine to the same engine, but between two different tables this time.
    # table_migrate(metadata.bind, metadata.bind, table, renamed_table, convert_fn=None, limit=100000)

def downgrade(metadata):
    fancy_table = metadata.tables['fancy_table']
    fancy_table.c.fancy_column.drop()

如果将此功能与sqlalchemy-migrate结合使用,它将变得更强大。这样,你就可以使用方言不可知论者SQLAlchemy DDLs来生成模式改变,但不必依赖于SqLalchemy迁移的修订跟踪和其他不必要的复杂性,这促使我写下这一点。

现在我们可以升级和降级我们的模式,例如:

grate upgrade "sqlite:///development.db" migration.001_change_fancy_column:upgrade --show-sql
grate upgrade "sqlite:///development.db" migration.001_change_fancy_column:downgrade --shoq-sql

也许这应该叫做upgrade以外的东西?也许是grade?无论如何…

性能说明

逐行重新插入(迁移)

数千行需要几秒钟,数百万行需要几分钟。详细信息取决于架构、服务器和特定数字。

就地架构更改(升级)

如果您没有执行完全的重新插入,那么这与使用任何其他模式迁移工具获得的效率差不多。通常以秒为单位。

有问题吗?想做贡献吗?

待办事项

  • 更具体的例子(填写代码todos)
  • 更多常用迁移操作的帮助程序
  • 在grate周围构建一个包装器来处理修订跟踪,并逐步完成升级过程,就像大多数主流迁移框架一样。

这不是炉排吗?

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Java:不解析XML的简单XML。例外   KIE Workbench的java自定义UI   java将元素从bucket移动到LinkedList,但有一个元素被完全删除   如何将java stream collect转换为scala   java运行AsynkTask多次不工作   java组织。xml。萨克斯。SAXParseException:cvccomplextype。2.4.c:匹配的通配符是严格的   java是一种计算排序算法所需时间的合适方法   java在O(logn)时间内对排序整数数组中具有相同数字的数字进行计数   xpages从当前数据库javaAgent调用另一个数据库的javaAgent   java如何在instagram中上传特定位置的所有照片   JavaApachePOI可以有效地删除多个列   java创建的对象数   java我可以在关闭连接时关闭Oracle JDBC自动提交吗?