【问题标题】:psycopg2: cursor.execute storing only table structure, no datapsycopg2: cursor.execute 只存储表结构,没有数据
【发布时间】:2020-08-06 12:51:52
【问题描述】:

我正在尝试使用 psycopg2 将我在代码中创建的一些表存储在 RDS 实例中。该脚本运行没有问题,我可以看到该表已正确存储在数据库中。但是,如果我尝试检索查询,我只会看到列,但看不到数据:

    import pandas as pd
    import psycopg2 
    
    test=pd.DataFrame({'A':[1,1],'B':[2,2]})
    
    #connect is a function to connect to the RDS instance
    connection= connect() 
    cursor=connection.cursor()

    query='CREATE TABLE test (A varchar NOT NULL,B varchar NOT NULL);'

    cursor.execute(query)
        
    connection.commit()

    cursor.close()
    connection.close()
    

此脚本运行没有问题,并从以下脚本打印出file_check

   connection=connect()
   # check if file already exists in SQL
   sql = """
    SELECT "table_name","column_name", "data_type", "table_schema"
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE "table_schema" = 'public'
    ORDER BY table_name  
    """
   file_check=pd.read_sql(sql, con=connection)

   connection.close()

我明白了:

table_name column_name          data_type table_schema
0       test           a  character varying       public
1       test           b  character varying       public

看起来不错。

但是运行以下命令:

   read='select * from public.test'
   df=pd.read_sql(read,con=connection)

返回:

Empty DataFrame
Columns: [a, b]
Index: []

有人知道为什么会这样吗?我似乎无法解决这个问题

【问题讨论】:

    标签: python sql pandas amazon-rds psycopg2


    【解决方案1】:

    Erm,你的第一个脚本一个 test_tbl 数据框,但它在定义后从未被引用过。

    你需要

    test_tbl.to_sql("test", connection)
    

    或类似实际写的。

    一个最小的例子:

    $ createdb so63284022
    $ python
    >>> import sqlalchemy as sa
    >>> import pandas as pd
    >>> test = pd.DataFrame({'A':[1,1],'B':[2,2], 'C': ['yes', 'hello']})
    >>> engine = sa.create_engine("postgres://localhost/so63284022")
    >>> with engine.connect() as connection:
    ...     test.to_sql("test", connection)
    ...
    >>>
    $ psql so63284022
    so63284022=# select * from test;
     index | A | B |   C
    -------+---+---+-------
         0 | 1 | 2 | yes
         1 | 1 | 2 | hello
    (2 rows)
    
    so63284022=# \d+ test
                                       Table "public.test"
     Column |  Type  | Collation | Nullable | Default | Storage  | Stats target | Description
    --------+--------+-----------+----------+---------+----------+--------------+-------------
     index  | bigint |           |          |         | plain    |              |
     A      | bigint |           |          |         | plain    |              |
     B      | bigint |           |          |         | plain    |              |
     C      | text   |           |          |         | extended |              |
    Indexes:
        "ix_test_index" btree (index)
    Access method: heap
    
    so63284022=#
    

    【讨论】:

    • 抱歉,问题中的错字。现已编辑。感谢您的关注
    • 你仍然没有对test(née test_tbl)做任何事情。
    • 另外,你不需要用 Pandas 手动创建表——如果你只做to_sql(),它会创建一个具有正确模式的表。
    • 我加了一个例子。
    • 感谢您的建议。然而,我能够找到解决 sqlalchemy 的方法。不过,您的示例也可以使用
    【解决方案2】:

    我能够解决这个问题: 正如@AKX 所指出的,我只是在创建表结构,而不是在填写表。

    我现在也导入import psycopg2.extras,然后:

       query='CREATE TABLE test (A varchar NOT NULL,B varchar NOT NULL);'
    
       cursor.execute(query)
    

    我添加了类似的内容:

       update_query='INSERT INTO test(A, B) VALUES(%s,%s) ON CONFLICT DO NOTHING' 
       psycopg2.extras.execute_batch(cursor, update_query, test.values)
    
       cursor.close()
       connection.close()
    

    在检查pd.read_sql 后,我的表格现在已正确填写

    【讨论】:

    • 如果您只是将pd.to_sql() 与SQLAlchemy 一起使用,则无需自己编写CREATE TABLEINSERT 语句。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多