【发布时间】:2021-03-07 14:33:26
【问题描述】:
使用 Python 和 SQLAlchemy,是否可以在链接到主键的 Postgresql 外键列中插入 None / NIL_UUID / NULL 值,两者都存储为 UUID?
-
None返回column none does not exist:
statement = "INSERT INTO tb_person (pk_person, first_name, last_name, fk_person_parent) VALUES ('9ce131...985
fea06', 'John', 'Doe', None)"
parameters = {}, context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7fbff5ea2730>
def do_execute(self, cursor, statement, parameters, context=None):
> cursor.execute(statement, parameters)
E psycopg2.errors.UndefinedColumn: column "none" does not exist
E LINE 1: '9ce131...985','John', 'Doe', None)
E ^
E HINT: Perhaps you meant to reference the column "tb_person.last_name".
../../.local/share/virtualenvs/project/lib/python3.8/site-packages/sqlalchemy/engine/default.py:593: UndefinedColumn
-
NIL_UUID(即用 0 组成的有效 UUID)返回psycopg2.errors.ForeignKeyViolation:
E psycopg2.errors.ForeignKeyViolation: insert or update on table "tb_person" violates foreign key constrain
t "tb_person_fk_person_parent_fkey"
E DETAIL: Key (fk_person_parent)=(00000000-0000-0000-0000-000000000000) is not present in table "tb_person
".
更多详情
我使用 SQLAlchemy 经典映射(SQLAlchemy Core),我的表是这样定义的:
tb_person = Table(
"tb_person",
metadata,
Column(
"pk_person",
UUID(as_uuid=True),
default=uuid.uuid4,
unique=True,
nullable=False
),
Column("first_name", String(255)),
Column("last_name", String(255)),
Column(
"fk_person_parent", UUID(as_uuid=True),
ForeignKey("tb_person.pk_person"),
nullable=True
)
)
映射器是这样定义的:
client_mapper = mapper(
domain.model.Person,
tb_person,
properties={
"child": relationship(domain.model.Person),
},
)
在 pk_person 字段中插入数据库中已存在的 UUID 时,单元测试运行良好。
【问题讨论】:
-
可以在
FOREIGN KEY字段中设置INSERTNULL值。您的NIL_UUID值不是NULL,因此它需要在引用表的PRIMARY KEY中输入一个条目。 -
@AdrianKlaver 谢谢,你用我所做的较短的术语提出了我的问题。当 None 和 NIL_UUID 都不起作用时,如何在 UUID 字段中插入 NULL?
-
您实际上并没有传入
None,而是传入了被视为列名的“None”。如果fk_person_parent允许NULL则不要在INSERT中包含该字段,并且将为该值设置NULL。您确实应该使用参数来传递值,然后None将正确适应INSERT上的NULL。 -
从 psycopg2 回溯中,该语句显示为“INSERT INTO tb_person (pk_person, first_name, last_name, fk_person_parent) VALUES ('9ce131...985fea06', 'John', 'Doe', None)" -它在查询中被插入为 None (而不是“None”),但谢谢我会使用参数再试一次。
-
是的,但是错误
psycopg2.errors.UndefinedColumn: column "none" does not exist显示,因为它在一个字符串中,所以它被双引号引起来,并被误认为是一个标识符(在这种情况下是一列)。这也是它被装箱的原因。
标签: python postgresql sqlalchemy