我正在生产中运行 mysql,但想在内存数据库中的 sqlite 中运行一个简单的测试。
旧版 mysql db 的表中的列是 mysql 特定类型,在声明性模型中声明(子类化 declarative_base)。我想在不去 mysql 的情况下运行一些简单的测试,因此需要换出模型的列。
我该怎么做呢?我试过写一个修补程序/解补丁程序来换出我的模型中的表,但是当我运行一些测试时,我得到
OperationalError: (OperationalError) near ")": syntax error u'\nCREATE TABLE my_table (\n)\n\n' ()
Run Code Online (Sandbox Code Playgroud)
这让我认为我没有正确修补列。
有谁知道我怎么能做到这一点?我究竟做错了什么?
目前,我创建新列并将全新的 Table 对象附加到__table__并保存旧表。
DB 已创建,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)
Run Code Online (Sandbox Code Playgroud)
我希望以下内容可以帮助您更好地处理此类修改。但是您的错误很奇怪,因为它在CREATE TABLE子句中没有列,所以我认为这不是您问题的直接答案/解决方案。
无论如何,与其完全替换表和列,不如尝试使用Custom SQL Constructs and Compilation Extension / Dialect-specific compiler rules。请参阅示例代码,该代码应该在不更改表定义的情况下为 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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3388 次 |
| 最近记录: |