Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用sqlalchemy orm从查询创建临时表_Python_Sql_Sqlalchemy - Fatal编程技术网

Python 使用sqlalchemy orm从查询创建临时表

Python 使用sqlalchemy orm从查询创建临时表,python,sql,sqlalchemy,Python,Sql,Sqlalchemy,我可以通过以下方式创建临时表: session.execute("CREATE TABLE temptable SELECT existingtable.id, " "existingtable.column2 FROM existingtable WHERE existingtable.id<100000") 如果不执行100000个session.query.add(诱惑(…)命令,如何使用现有表的某些选定内容填充临时表?或者,有没有一种方法可以从类似于上述纯SQL版本的查询

我可以通过以下方式创建临时表:

session.execute("CREATE TABLE temptable SELECT existingtable.id, "
    "existingtable.column2 FROM existingtable WHERE existingtable.id<100000")

如果不执行100000个
session.query.add(诱惑(…)
命令,如何使用
现有表的某些选定内容填充
临时表
?或者,有没有一种方法可以从类似于上述纯SQL版本的查询中创建表?

这不完全是ORM,但要创建表,我首先要克隆表结构(请参见下面示例中的
cloneTable
)。为了复制数据,我将使用

编辑:自0.8.3版以来,SqlAlchemy支持开箱即用。因此,可以直接替换下面示例中的InsertFromSelect类和相应的访问者,不再需要它们。出于历史原因,我将原始示例保持不变

下面是一个工作示例

from sqlalchemy import Table
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import UpdateBase

class InsertFromSelect(UpdateBase):
    def __init__(self, table, select):
        self.table = table
        self.select = select

@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
    return "INSERT INTO %s %s" % (
        compiler.process(element.table, asfrom=True),
        compiler.process(element.select)
    )

def cloneTable(name, table, metadata):
    cols = [c.copy() for c in table.columns]
    constraints = [c.copy() for c in table.constraints]
    return Table(name, metadata, *(cols + constraints))

# test data
from sqlalchemy import MetaData, Column, Integer
from sqlalchemy.engine import create_engine
e = create_engine('sqlite://')
m = MetaData(e)
t = Table('t', m, Column('id', Integer, primary_key=True),
          Column('number', Integer))
t.create()
e.execute(t.insert().values(id=1, number=3))
e.execute(t.insert().values(id=9, number=-3))

# create temp table
temp = cloneTable('temp', t, m)
temp.create()

# copy data
ins = InsertFromSelect(temp, t.select().where(t.c.id>5))
e.execute(ins)

# print result
for r in e.execute(temp.select()):
    print(r)

只是古玩。。如果您使用第一种方法创建临时表的定义,它会工作吗?例如,create table tablename(id primarykey,column1)Insert into tablename select id,column2 from existing table where…@AJP Yes,我想这就是答案。不幸的是,没有与INSERT INTO等效的SA ORM,也没有简单的方法将相对复杂的查询编译成sql语句。不幸的是,在运行以下命令时,我遇到了一个importerror:importerror:cannotimportname UpdateBase。使用InsertFromSelect示例时出现类似的导入错误。我正在使用SA0.5。7@Paul:啊,此功能仅在SA 0.6之后可用。我已经用0.7.5测试过了,答案很好。我真的需要这个解决方案。我有这个问题要问你。你的方法是最好的方法吗。正如在create table first中,然后执行insert from select?@Ranjith:对于这种情况,我可能会创建自己的自定义SQL构造
SelectInto
(类似于上面的
InsertFromSelect
),它利用了大多数SQL方言中可用的语法(例如,SQL Server的
SELECT*FROM OldTable
或Oracle或SQLite中的
CREATE TABLE NewTable AS SELECT*FROM OldTable
)。您还可以查看物化视图(Oracle)或索引视图(SQL Server)。感谢Stephan的输入
from sqlalchemy import Table
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import UpdateBase

class InsertFromSelect(UpdateBase):
    def __init__(self, table, select):
        self.table = table
        self.select = select

@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
    return "INSERT INTO %s %s" % (
        compiler.process(element.table, asfrom=True),
        compiler.process(element.select)
    )

def cloneTable(name, table, metadata):
    cols = [c.copy() for c in table.columns]
    constraints = [c.copy() for c in table.constraints]
    return Table(name, metadata, *(cols + constraints))

# test data
from sqlalchemy import MetaData, Column, Integer
from sqlalchemy.engine import create_engine
e = create_engine('sqlite://')
m = MetaData(e)
t = Table('t', m, Column('id', Integer, primary_key=True),
          Column('number', Integer))
t.create()
e.execute(t.insert().values(id=1, number=3))
e.execute(t.insert().values(id=9, number=-3))

# create temp table
temp = cloneTable('temp', t, m)
temp.create()

# copy data
ins = InsertFromSelect(temp, t.select().where(t.c.id>5))
e.execute(ins)

# print result
for r in e.execute(temp.select()):
    print(r)