[英]SQLAlchemy temporary table with Declarative Base
I need a temporary table in my programme.我的程序中需要一个临时表。 I have seen that this can be achieved with the "mapper" syntax in this way:我已经看到这可以通过“映射器”语法以这种方式实现:
t = Table(
't', metadata,
Column('id', Integer, primary_key=True),
# ...
prefixes=['TEMPORARY'],
)
But, my whole code is using the declarative base, it is what I understand, and I would like to stick to it.但是,我的整个代码都使用声明性基础,这是我的理解,我想坚持下去。 There is the possibility of using a hybrid approach but if possible I'd avoid it.有可能使用混合方法,但如果可能的话,我会避免它。
This is a simplified version of how my declarative class looks like:这是我的声明类的简化版本:
import SQLAlchemy as alc
class Tempo(Base):
"""
Class for temporary table used to process data coming from xlsx
@param Base Declarative Base
"""
# TODO: make it completely temporary
__tablename__ = 'tempo'
drw = alc.Column(alc.String)
date = alc.Column(alc.Date)
check_number = alc.Column(alc.Integer)
Thanks in advance!提前致谢!
EDITED WITH THE NEW PROBLEMS:使用新问题进行编辑:
Now the class looks like this:现在这个类看起来像这样:
import SQLAlchemy as alc
class Tempo(Base):
"""
Class for temporary table used to process data coming from xlsx
@param Base Declarative Base
"""
# TODO: make it completely temporary
__tablename__ = 'tempo'
__table_args__ = {'prefixes': ['TEMPORARY']}
drw = alc.Column(alc.String)
date = alc.Column(alc.Date)
check_number = alc.Column(alc.Integer)
And when I try to insert data in this table, I get the following error message:当我尝试在此表中插入数据时,我收到以下错误消息:
sqlalchemy.exc.OperationalError: (OperationalError) no such table:
tempo u'INSERT INTO tempo (...) VALUES (?, ?, ?, ?, ?, ?, ?, ?)' (....)
It seems the table doesn't exist just by declaring it.仅通过声明该表似乎不存在。 I have seen something like create_all() that might be the solution for this (it's funny to see how new ideas come while explaining thoroughly)我见过像 create_all() 这样的东西,它可能是解决这个问题的方法(在彻底解释的同时看到新想法是如何产生的,这很有趣)
Then again, thank you very much!再说一次,非常感谢!
Is it possible to use __table_args__
?是否可以使用__table_args__
? See http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative.html#table-configuration请参阅http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative.html#table-configuration
class Tempo(Base):
"""
Class for temporary table used to process data coming from xlsx
@param Base Declarative Base
"""
# TODO: make it completely temporary
__tablename__ = 'tempo'
__table_args__ = {'prefixes': ['TEMPORARY']}
drw = alc.Column(alc.String)
date = alc.Column(alc.Date)
check_number = alc.Column(alc.Integer)
Old question, but if anyone out there wants to create a temp table from an existing declarative table model on the fly rather than having it always be a part of your model/code, you can try the following approach.老问题,但如果有人想从现有的声明性表模型动态创建临时表,而不是让它始终成为模型/代码的一部分,您可以尝试以下方法。 Copying __table_args__
is a little tricky since it can have multiple formats and any Index
objects need to be recreated so they aren't associated with the old table.复制__table_args__
有点棘手,因为它可以有多种格式,并且需要重新创建任何Index
对象,这样它们就不会与旧表相关联。
import time
from sqlalchemy.schema import CreateTable
def copy_table_args(model, **kwargs):
"""Try to copy existing __table_args__, override params with kwargs"""
table_args = model.__table_args__
if isinstance(table_args, tuple):
new_args = []
for arg in table_args:
if isinstance(arg, dict):
table_args_dict = arg.copy()
table_args_dict.update(**kwargs)
new_args.append(arg)
elif isinstance(arg, sa.Index):
index = sa.Index(
arg.name,
*[col for col in arg.columns.keys()],
unique=arg.unique,
**arg.kwargs,
)
new_args.append(index)
else:
# TODO: need to handle Constraints
raise Exception(f"Unhandled table arg: {arg}")
table_args = tuple(new_args)
elif isinstance(table_args, dict):
table_args = {
k: (v.copy() if hasattr(v, "copy") else v) for k, v in table_args.items()
}
table_args.update(**kwargs)
else:
raise Exception(f"Unexpected __table_args__ type: {table_args}")
return table_args
def copy_table_from_model(conn, model, **kwargs):
model_name = model.__name__ + "Tmp"
table_name = model.__table__.name + "_" + str(time.time()).replace(".", "_")
table_args = copy_table_args(model, extend_existing=True)
args = {c.name: c.copy() for c in model.__table__.c}
args["__tablename__"] = table_name
args["__table_args__"] = table_args
copy_model = type(model_name, model.__bases__, args)
print(str(CreateTable(copy_model.__table__)))
copy_model.__table__.create(conn)
return copy_model
def temp_table_from_model(conn, model, **kwargs):
return copy_table_from_model(conn, model, prefixes=["TEMPORARY"])
Note: I haven't added logic to handle copying Constraints, and this is lightly tested against MySQL.注意:我没有添加处理复制约束的逻辑,这是针对 MySQL 的轻微测试。 Also note that if you do this with non-temporary tables and auto-named indexes (ie Column(..., index=True)
) then this may not play nice with alembic
.另请注意,如果您使用非临时表和自动命名索引(即Column(..., index=True)
)执行此操作,那么这可能不适用于alembic
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.