英文:
Entity to support multiple dialects
问题
我有一个为PostgreSQL方言编写的SQLAlchemy实体,它使用了 server_default=func.clock_timestamp()
:
row_created = sa.Column('row_created_', sa.DateTime(timezone=True), server_default=func.clock_timestamp(), nullable=False)
我还需要在SQLite中使用它,但会抛出错误:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unknown function: clock_timestamp()
如何让这个在SQLAlchemy中工作?仅为SQLite定义 server_default
?有条件地仅为特定方言添加整个列?以某种方式使 clock_timestamp()
在SQLite中可用(我不关心函数会执行什么,只要不失败)?
英文:
I have an SQLAlchemy entity written for PostgreSQL dialect and it uses server_default=func.clock_timestamp()
:
row_created = sa.Column('row_created_', sa.DateTime(timezone=True), server_default=func.clock_timestamp(), nullable=False)
I also need to use it with SQLite, which throws an error:
> sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unknown function: clock_timestamp()
How do I make this work with SQLAlchemy? Define the server_default
only for SQLite? Conditionally add entire column only for specific dialect? Somehow make clock_timestamp()
known to SQLite (I don't care what the function will do, as long as it does not fail)?
答案1
得分: 1
你可以使用以下代码来设置服务器默认值:text("CURRENT_TIMESTAMP")
class TimeStamp(Base):
__tablename__ = "timestamp"
id: Mapped[int] = mapped_column(
primary_key=True,
)
datetime_with_tz: Mapped[datetime] = mapped_column(
types.DateTime(timezone=True),
server_default=text("CURRENT_TIMESTAMP"),
)
这将创建一个具有以下SQL的表格:
PostgresSQL:
CREATE TABLE timestamp (
id SERIAL NOT NULL,
datetime_with_tz TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
)
SQLite:
CREATE TABLE timestamp (
id INTEGER NOT NULL,
datetime_with_tz DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
)
如果你必须在PostgreSQL上使用clock_timestamp()
,你可以将服务器默认值设置为:
server_default=text("CURRENT_TIMESTAMP") if use_sqlite else text("clock_timestamp()"),
PostgreSQL:
CREATE TABLE timestamp (
id SERIAL NOT NULL,
datetime_with_tz TIMESTAMP WITH TIME ZONE DEFAULT clock_timestamp() NOT NULL,
PRIMARY KEY (id)
)
SQLite:
CREATE TABLE timestamp (
id INTEGER NOT NULL,
datetime_with_tz DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
)
你也可以使用"default",以使它在两个数据库上都能工作:
timestamp_auto = Annotated[
datetime.datetime,
mapped_column(
default=datetime.datetime.now,
),
]
class TimeStamp(Base):
__tablename__ = "timestamp"
id: Mapped[int] = mapped_column(
primary_key=True,
)
datetime_with_tz: Mapped[timestamp_auto] = mapped_column(
types.DateTime(timezone=True),
)
英文:
You can use: text("CURRENT_TIMESTAMP")
for the server default:
class TimeStamp(Base):
__tablename__ = "timestamp"
id: Mapped[int] = mapped_column(
primary_key=True,
)
datetime_with_tz: Mapped[datetime] = mapped_column(
types.DateTime(timezone=True),
server_default=text("CURRENT_TIMESTAMP"),
)
This will create a table with the following SQL:
PostgresSQL:
CREATE TABLE timestamp (
id SERIAL NOT NULL,
datetime_with_tz TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
)
SQLite:
CREATE TABLE timestamp (
id INTEGER NOT NULL,
datetime_with_tz DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
)
If you must use clock_timestamp()
on PostgreSQL, you can set server default
to:
server_default=text("CURRENT_TIMESTAMP") if use_sqlite else text("clock_timestamp()"),
postgres
CREATE TABLE timestamp (
id SERIAL NOT NULL,
datetime_with_tz TIMESTAMP WITH TIME ZONE DEFAULT clock_timestamp() NOT NULL,
PRIMARY KEY (id)
)
sqlite
CREATE TABLE timestamp (
id INTEGER NOT NULL,
datetime_with_tz DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
)
You can also use "default" for it to work on both databases.
timestamp_auto = Annotated[
datetime.datetime,
mapped_column(
default=datetime.datetime.now,
),
]
class TimeStamp(Base):
__tablename__ = "timestamp"
id: Mapped[int] = mapped_column(
primary_key=True,
)
datetime_with_tz: Mapped[timestamp_auto] = mapped_column(
types.DateTime(timezone=True),
)
答案2
得分: 0
我从我的一位同事那里得到了一个提示,我最终采用了它,它在postgresql和sqlite都运行良好。
server_default=func.now()
据我所知,这与func.clock_timestamp()
相同,但clock_timestamp()
是特定于postgresql的,而now()
受到多个数据库的支持。
英文:
I got a tip from a colleague of mine, which I ended up using and it works fine for both postgresql as well as sqlite.
server_default=func.now()
afaik it is the same as func.clock_timestamp(), but clock_timestamp() is postgresql-specific and now() is supoported by several DBs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论