Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.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引擎的多个连接会产生不同的信息?_Python_Postgresql_Sqlalchemy_Temp Tables - Fatal编程技术网

Python 为什么来自同一sqlalchemy引擎的多个连接会产生不同的信息?

Python 为什么来自同一sqlalchemy引擎的多个连接会产生不同的信息?,python,postgresql,sqlalchemy,temp-tables,Python,Postgresql,Sqlalchemy,Temp Tables,我正在使用PostgreSQL 9.3和SQLAlchemy 1.0.11 我有如下代码: import sqlalchemy as sa engine = sa.create_engine('postgresql+psycopg2://me@myhost/mydb') conn = engine.connect() metadata = sa.MetaData() # Real table has more columns mytable = sa.Table( 'my_temp

我正在使用PostgreSQL 9.3和SQLAlchemy 1.0.11

我有如下代码:

import sqlalchemy as sa

engine = sa.create_engine('postgresql+psycopg2://me@myhost/mydb')
conn = engine.connect()

metadata = sa.MetaData()

# Real table has more columns
mytable = sa.Table(
    'my_temp_table', metadata,
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('something', sa.String(200)),
    prefixes=['TEMPORARY'],
)

metadata.create_all(engine)

pg_conn = engine.raw_connection()
with pg_conn.cursor() as cursor:
    cursor.copy_expert('''COPY my_temp_table (id, something)
                          FROM STDIN WITH CSV''',
                       open('somecsvfile', 'r'))
现在这一切都很好——cursor.rowcount报告插入的预期行数。我甚至可以运行游标。执行“从我的临时表中选择计数”;printcursor.fetchone,它将显示相同的内容。问题是当我尝试从SQLAlchemy的连接运行查询时,例如

    result = conn.execute(sa.text('SELECT count(*) FROM my_temp_table'))
不管我把它放在哪里。我试过几个地方:

在带块的内部 在街区外 在光标之后。关闭 在pg_连接关闭后 似乎什么都不起作用-无论我从何处运行查询,它都会伴随以下内容:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) relation "my_temp_table" does not exist
有趣的是,如果我用try/except包装代码,那么我就可以执行cursor.execute。。。在except块中成功执行

事实上,现在我写出来了,似乎在任何地方使用sqlalchemy连接都看不到这些表的存在

那么是什么原因呢?为什么我的SQLAlchemy连接看不到这些表,而postgres engine.raw_连接看不到这些表

编辑: 为了进一步揭开谜团,如果我在metadata.create_allengine之后创建连接,它就会工作!嗯,有点


我可以从表中选择,但当我获得engine.raw\u连接时,它会失败。复制\u expert,因为它找不到表。

好吧,这并不能回答为什么,但它是如何实现我想要的

而不是:

pg_conn = engine.raw_connection()

with pg_conn.cursor() as cursor:
只需将其替换为:

with conn.connection.cursor() as cursor:

通过.connection属性创建SQLAlchemy连接对象。无论其中包含什么魔力,都是正确的。

首先要注意的是,临时表只对创建它们的连接可见

第二,引擎不封装单个连接;它管理着一个网络

最后,指出直接在Engine.executeselect上执行的操作。。。在他们的示例中,将在内部获取并释放他们自己的连接

考虑到所有这些,很清楚您的示例中发生了什么:

conn=engine.connect从池中获取连接1。 metadata.create_allengine隐式获取连接2,因为从引擎的角度来看,1仍在使用中,使用它创建表,并将其释放回池。 pg_conn=engine.raw_连接再次获取2,因此通过该对象执行的复制仍然可以看到该表。 conn仍在使用1,您通过此对象所做的任何操作都无法查看您的临时表。 在第二种情况下:

metadata.create_allengine隐式获取/使用/释放连接1。 conn=engine.connect获取并保持1。 pg_conn=engine.raw_连接获取2,副本无法找到临时表。
这个故事的寓意是:如果你正在做一些依赖于连接状态的事情,你最好确定你正在使用哪个连接。直接在引擎上运行命令对于独立操作来说是很好的,但是对于涉及临时表的任何操作,您都应该获得一个连接,并在包括表创建在内的每一个步骤中坚持使用它,我建议您将其更改为元数据。创建\u allconn。

Nice。我甚至都不知道,创造奥尔康是一件事。工作起来像个符咒,而且可能没有那么神奇@韦恩:你们都会接受任何东西。我想这适用于大多数需要数据库连接的事情。有趣的是,我又遇到了同样的问题。未来的我:你现在可能已经忘记了,但你需要使用conn=engine.connect;pg_conn=conn.connection以获取原始连接,因此您可以执行metadata.create_allconn,然后稍后使用原始连接。