Jam*_*son 10 python postgresql sqlalchemy temp-tables
似乎SQLAlchemy的最大缺点是在处理临时表时需要几个步骤.例如,一个非常常见的用例是创建一个特定于一个任务的临时表,在其中抛出一些数据,然后加入它.
对于初学者来说,声明一个临时表是冗长的,并且是有限的.请注意,在这个例子中我必须编辑它,因为我的类实际上继承了一个基类,所以我在这里给出的可能稍微不正确.
@as_declarative(metaclass=MetaBase)
class MyTempTable(object):
__tablename__ = "temp"
__table_args__ = {'prefixes': ['TEMPORARY']}
id = Column(Integer(), primary_key=True)
person_id = Column(BigInteger())
a_string = Column(String(100))
Run Code Online (Sandbox Code Playgroud)
创建它是不直观的:
MyTempTable.__table__.create(session.bind)
Run Code Online (Sandbox Code Playgroud)
除非我做一些有创意的事情来使用ON COMMIT DROP进行渲染,否则我还必须记住明确删除它:
MyTempTable.__table__.drop(session.bind)
Run Code Online (Sandbox Code Playgroud)
而且,除非临时表完成"顶级",否则我刚刚给出的内容甚至不起作用.我还没有完全弄明白(因为不想花时间调查它为什么不起作用),但基本上我尝试使用session.begin_nested()和你在嵌套事务中以这种方式创建一个临时表最终得到一个错误,说该关系不存在.但是,我有几种情况我在嵌套事务中创建临时表以进行单元测试,它们工作得很好.检查回声输出,看来差别在于一个在BEGIN语句之前呈现,而另一个在它之后呈现.这是使用Postgresql.
什么在嵌套事务中工作,并且坦率地为您节省了大量时间,就是输入该死的sql并使用session.execute执行它.
session.execute(text(
"CREATE TEMPORARY TABLE temp ("
" id SERIAL,"
" person_id BIGINT,"
" a_string TEXT"
") ON COMMIT DROP;"
))
Run Code Online (Sandbox Code Playgroud)
当然,如果你这样做,你仍然需要一个相应的表模型来使用ORM功能,或者必须坚持使用原始的SQL查询,这首先会破坏SQLAlchemy的目的.
我想知道我是否在这里遗漏了一些东西,或者有人提出了一个更优雅的解决方案.
我将 ORM 与 Core 一起使用。ORM 保留用于更高级别的操作。对于大量数据和临时表,Core 更方便。例子:
temptbl_name = 'temp_del_dup_pk_{}'.format(datestamp)
temptbl = Table(temptbl_name, metadata, Column('col1', Integer, index=True),..., extend_existing=True)
temptbl.create(engine)
Run Code Online (Sandbox Code Playgroud)
更新 这是一个简单的函数,可以动态生成临时表 ORM 定义:
def temp_table(name, cols):
args = dict(col1=Column(Integer, index=True),...)
args['__tablename__'] = name
args['__table_args__'] = dict(extend_existing=True)
return type(name, (Base,), args)
Run Code Online (Sandbox Code Playgroud)
镜像现有表的列可能很有用:
def temp_table(name, base_table):
args = {c.name:c.copy() for c in base_table.__table__.c}
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3636 次 |
| 最近记录: |