SQLAlchemy insert values into reflected table 结果全部为 NULL 条目

SQLAlchemy insert values into reflected table results in NULL entries all across

以下代码每次尝试都会导致 None () 跨行。下面的 query.values() 代码只是一个缩短的行,以使事情不那么复杂。此外,我在地址字段中插入字典作为 JSON 时遇到问题,但这是另一个问题。

CREATE TABLE public.customers (
    id SERIAL,
    email character varying(255)  NULL,
    name character varying(255)  NULL,
    phone character varying(16)  NULL,
    address jsonb  NULL,
    shipping jsonb  NULL,
    currency character varying(3)  NULL,
    metadata jsonb[]  NULL,
    created bigint  NULL,
    uuid uuid DEFAULT uuid_generate_v4() NOT NULL,
    PRIMARY KEY (uuid)
);
from sqlalchemy import *
from sqlalchemy.orm import Session

# Create engine, metadata, & session
engine = create_engine('postgresql://postgres:password@database/db', future=True)
metadata = MetaData(bind=engine)
session = Session(engine)

# Create Table
customers = Table('customers', metadata, autoload_with=engine)

query = customers.insert()
query.values(email="test@test.com", \
             name="testy testarosa", \
             phone="+12125551212", \
             address='{"city": "Cities", "street": "123 Main St", \
                        "state": "CA", "zip": "10001"}')


session.execute(query)
session.commit()
session.close()

# Now to see results
stmt = text("SELECT * FROM customers")
response = session.execute(stmt)

for result in response:
    print(result)

# Results in None in the fields I explicitly attempted 
(1, None, None, None, None, None, None, None, 1, None, None, None, None, UUID('9112a420-aa36-4498-bb56-d4129682681c'))

我不知道你说的是什么意思

The query.values() code below is just a shortened line so as to keep things less complicated.

所以我可能没有正确理解这个问题。 无论如何,这里的问题是您分别执行 insert()values(),而它本来是要“链接”的。

做类似的事情:

query = customers.insert().values(email="test@test.com", name="testy testarosa", phone="+12125551212", address='{"city": "Cities", "street": "123 Main St", "state": "CA", "zip": "10001"}')

会起作用。

文档:https://docs.sqlalchemy.org/en/14/core/selectable.html#sqlalchemy.sql.expression.TableClause.insert

PS:我也没有遇到 JSON 字段的任何问题。也许是 PG 版本的东西?

调用 query.values() return 一个新的 insert 实例,而不是就地修改现有实例。此 return 值必须分配给变量,否则它将无效。

您可以迭代构建插入

query = customers.insert()
query = query.values(...)
session.execute(query)

调用为Karolus K. suggests in their

query = customers.insert().values(...)

关于 address 列,您正在插入一个已经序列化为 JSON 的字典。该值在插入期间再次序列化,因此数据库中的值最终如下所示:

test# select address from customers;
                                                       address                                                        
══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
 "{\"city\": \"Cities\", \"street\": \"123 Main St\",                         \"state\": \"CA\", \"zip\": \"10001\"}"
(1 row)

并且不适合作为 JSON 对象进行查询(因为它是 JSON 化的 字符串

test# select address->'state' AS state from customers;
 state 
═══════
 ¤
(1 row)

您可能会发现传递原始字典会更好,从而将此值存储在数据库中:

test# select address from customers;
                                  address                                   
════════════════════════════════════════════════════════════════════════════
 {"zip": "10001", "city": "Cities", "state": "CA", "street": "123 Main St"}
(1 row)

可以作为 JSON 对象查询:

test# select address->'state' AS state from customers;
 state 
═══════
 "CA"
(1 row)