[英]Select from table defined by SQLAlchemy declarative_base
[英]SQLAlchemy temporary table with Declarative Base
我的程序中需要一個臨時表。 我已經看到這可以通過“映射器”語法以這種方式實現:
t = Table(
't', metadata,
Column('id', Integer, primary_key=True),
# ...
prefixes=['TEMPORARY'],
)
在這里看到
但是,我的整個代碼都使用聲明性基礎,這是我的理解,我想堅持下去。 有可能使用混合方法,但如果可能的話,我會避免它。
這是我的聲明類的簡化版本:
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)
提前致謝!
使用新問題進行編輯:
現在這個類看起來像這樣:
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)
當我嘗試在此表中插入數據時,我收到以下錯誤消息:
sqlalchemy.exc.OperationalError: (OperationalError) no such table:
tempo u'INSERT INTO tempo (...) VALUES (?, ?, ?, ?, ?, ?, ?, ?)' (....)
僅通過聲明該表似乎不存在。 我見過像 create_all() 這樣的東西,它可能是解決這個問題的方法(在徹底解釋的同時看到新想法是如何產生的,這很有趣)
再說一次,非常感謝!
是否可以使用__table_args__
? 請參閱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)
老問題,但如果有人想從現有的聲明性表模型動態創建臨時表,而不是讓它始終成為模型/代碼的一部分,您可以嘗試以下方法。 復制__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"])
注意:我沒有添加處理復制約束的邏輯,這是針對 MySQL 的輕微測試。 另請注意,如果您使用非臨時表和自動命名索引(即Column(..., index=True)
)執行此操作,那么這可能不適用於alembic
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.