将
RDBMS_URI
env var 设置为像 postgresql://username:password@host/database
这样的连接字符串,然后在带有 PostgreSQL 15 和 SQLalchemy 1.14 的 Python 3.9 上运行:
from os import environ
from sqlalchemy import Boolean, Column, Identity, Integer
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class Tbl(Base):
__tablename__ = 'Tbl'
__has_error__ = Column(Boolean)
id = Column(Integer, primary_key=True, server_default=Identity())
engine = create_engine(environ["RDBMS_URI"])
Base.metadata.create_all(engine)
检查数据库:
=> \d "Tbl"
Table "public.Tbl"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+----------------------------------
id | integer | | not null | generated by default as identity
Indexes:
"Tbl_pkey" PRIMARY KEY, btree (id)
如何强制使用双下划线的列名?
我相信声明性机制显式地从映射过程中排除名称以双下划线开头的属性(基于 this 和 this)。因此,您的
__has_error__
列不会在目标表中创建。
至少有两种可能的解决方法。首先,您可以给模型属性起一个不同的名称,例如:
_has_error = Column('__has_error__', BOOLEAN)
这将创建数据库列
__has_error__
,可通过 Tbl._has_error
* 访问。
如果您希望模型的 attribute 为
__has_error__
,那么您可以通过使用命令式映射来实现。
import sqlalchemy as sa
from sqlalchemy import orm
mapper_registry = orm.registry()
tbl = sa.Table(
'tbl',
mapper_registry.metadata,
sa.Column('__has_error__', sa.Boolean),
sa.Column(
'id', sa.Integer, primary_key=True, server_default=sa.Identity()
),
)
class Tbl:
pass
mapper_registry.map_imperatively(Tbl, tbl)
mapper_registry.metadata.create_all(engine)
* 我尝试使用 synonym 将
__has_error__
映射到 _has_error
但似乎不起作用。它可能也被排除在映射器中,但我没有进一步调查。