6

我在生产中运行 mysql,但想在内存数据库中的 sqlite 中运行一个简单的测试。

旧版 mysql 数据库的表具有 mysql 特定类型的列,这些列在声明性模型中声明(子类化 declarative_base)。我想在不使用 mysql 的情况下运行一些简单的测试,因此需要交换模型的列。

我该怎么做呢?我已经尝试编写一个补丁程序/取消补丁程序来换出我模型中的,但是当我运行一些测试时,我得到了

OperationalError: (OperationalError) near ")": syntax error u'\nCREATE TABLE my_table (\n)\n\n' ()

这使我认为我没有正确修补列。

有谁知道我该怎么做?我究竟做错了什么?

目前,我创建新列并将全新的 Table 对象附加到__table__旧表并保存。

数据库已创建,create_all() 已创建,并且 convert_columns 在 setUp 中运行。drop_all() 和 revert_columns 在我的测试中的 tearDown 期间运行

mysql_sqlite_mapping = {INTEGER: Integer,
                        MEDIUMINT: Integer,
                        TEXT: text}    

def convert_columns(self, my_class, mapping):
    for column in my_class.__table__.columns:
        if type(column.type) in mapping:
            replacement_col = Column(column.name,
                                     mapping[type(column.type)],
                                     primary_key=column.primary_key,
                                     nullable=column.nullable,
                                     key=column.key,
                                     unique=column.unique)

            converted_columns.append(replacement_col)

    self.registry[my_class] = my_class.__table__

    my_class.__table__.metadata.remove(my_class.__table__)
    my_class.__table__ = Table(my_class.__table__.name,
                               my_class.__table__.metadata)

    for column in converted_columns:
        my_class.__table__.append_column(column)

    return my_class

def revert_columns(self, my_class):
    saved_table = self.registry[my_class]

    metadata = my_class.__table__.metadata
    my_class.__table__.metadata.remove(my_class.__table__)

    model_class.__table__ = Table(saved_table.name,
                                  metadata)

    for column in saved_table.columns:
        column.table = None
        my_class.__table__.append_column(column)

    self.registry.pop(my_class)
4

1 回答 1

8

我希望下面的内容可以帮助您更好地处理这些修改。但是您的错误很奇怪,因为它在CREATE TABLE子句中没有列,所以我认为这不是您问题的直接答案/解决方案。

无论如何,与其完全替换表和列,不如尝试使用自定义 SQL 构造和编译扩展/特定方言的编译规则。请参阅应该为 sqlite 生成正确 SQL 语句而不更改表定义的示例代码:

from sqlalchemy.ext.compiler import compiles
from sqlalchemy.dialects.mysql import MEDIUMINT, INTEGER, TEXT

@compiles(MEDIUMINT, 'sqlite')
def compile_MEDIUMINT(element, compiler, **kw):
    """ Handles mysql MEDIUMINT datatype as Integer in sqlite.  """
    return compiler.visit_integer(element, **kw)

@compiles(INTEGER, 'sqlite')
def compile_INTEGER(element, compiler, **kw):
    """ Handles mysql INTEGER datatype as Integer in sqlite.  """
    return compiler.visit_integer(element, **kw)


@compiles(TEXT, 'sqlite')
def compile_TEXT(element, compiler, **kw):
    """ Handles mysql TEXT datatype as text in sqlite.  """
    return compiler.visit_text(element, **kw)
于 2012-05-14T10:13:30.957 回答