[英]How to define a table without primary key with SQLAlchemy?
我有一張沒有primary key
。 而且我真的不想將此約束應用於此表。
在SQLAlchemy 中,我通過以下方式定義了表類:
class SomeTable(Base):
__table__ = Table('SomeTable', meta, autoload=True, autoload_with=engine)
當我嘗試查詢此表時,我得到:
ArgumentError: Mapper Mapper|SomeTable|SomeTable could not assemble any primary key columns for mapped table 'SomeTable'.
如何失去每個表必須有一個主鍵的約束?
我知道只有一種方法可以繞過 SQL Alchemy 中的主鍵約束 - 將特定的一列或多列作為主鍵映射到您的表,即使它們本身不是主鍵。 http://docs.sqlalchemy.org/en/latest/faq/ormconfiguration.html#how-do-i-map-a-table-that-has-no-primary-key 。
對此沒有適當的解決方案,但有解決方法:
將參數 primary_key 添加到沒有主鍵的現有列將起作用。
class SomeTable(Base):
__table__ = 'some_table'
some_other_already_existing_column = Column(..., primary_key=True) # just add primary key to it whether or not this column is having primary key or not
只需在ORM 層上聲明一個新的虛擬列,而不是在實際的 DB 中。 只需在 SQLalchemy 模型中定義
class SomeTable(Base):
__table__ = 'some_table'
column_not_exist_in_db = Column(Integer, primary_key=True) # just add for sake of this error, dont add in db
Oracle 數據庫秘密地存儲稱為rowid
東西來唯一地定義表中的每條記錄,即使該表沒有主鍵。 我通過構建我的 ORM 對象解決了我缺少主鍵的問題(這不是我造成的!),例如:
class MyTable(Base)
__tablename__ = 'stupid_poorly_designed_table'
rowid = Column(String, primary_key=True)
column_a = Column(String)
column_b = Column(String)
...
您可以通過運行查看rowid
實際外觀(我相信這是一個十六進制值)
SELECT rowid FROM stupid_poorly_designed_table
GO
這是使用__mapper_args__
和合成 primary_key的示例。 因為表是面向時間序列的數據,所以不需要主鍵。 所有行都可以是具有(時間戳,對)元組的唯一地址。
class Candle(Base):
__tablename__ = "ohlvc_candle"
__table_args__ = (
sa.UniqueConstraint('pair_id', 'timestamp'),
)
#: Start second of the candle
timestamp = sa.Column(sa.TIMESTAMP(timezone=True), nullable=False)
open = sa.Column(sa.Float, nullable=False)
close = sa.Column(sa.Float, nullable=False)
high = sa.Column(sa.Float, nullable=False)
low = sa.Column(sa.Float, nullable=False)
volume = sa.Column(sa.Float, nullable=False)
pair_id = sa.Column(sa.ForeignKey("pair.id"), nullable=False)
pair = orm.relationship(Pair,
backref=orm.backref("candles",
lazy="dynamic",
cascade="all, delete-orphan",
single_parent=True, ), )
__mapper_args__ = {
"primary_key": [pair_id, timestamp]
}
MSSQL 測試
我知道這個線程很古老,但我花了太長時間才讓它工作而沒有分享它:)
from sqlalchemy import Table, event
from sqlalchemy.ext.compiler import compiles
from sqlalchemy import Column
from sqlalchemy import Integer
class RowID(Column):
pass
@compiles(RowID)
def compile_mycolumn(element, compiler, **kw):
return "row_number() OVER (ORDER BY (SELECT NULL))"
@event.listens_for(Table, "after_parent_attach")
def after_parent_attach(target, parent):
if not target.primary_key:
# if no pkey create our own one based on returned rowid
# this is untested for writing stuff - likely wont work
logging.info("No pkey defined for table, using rownumber %s", target)
target.append_column(RowID('row_id', Integer, primary_key=True))
一種方法:在 SQLAlchemy ORM 中,要映射到特定表,必須至少有一個列指定為主鍵列; 多列復合主鍵當然也是完全可能的。 這些列不需要被數據庫知道為主鍵列。 列只需要像主鍵一樣運行,例如行的不可為空的唯一標識符。
我的代碼:
from ..meta import Base, Column, Integer, Date
class ActiveMinutesByDate(Base):
__tablename__ = "user_computer_active_minutes_by_date"
user_computer_id = Column(Integer(), nullable=False, primary_key=True)
user_computer_date_check = Column(Date(), default=None, primary_key=True)
user_computer_active_minutes = Column(Integer(), nullable=True)
我找到的解決方案是向表中添加一個自動遞增的主鍵列,然后將其用作主鍵。 數據庫應該處理除此之外的所有其他事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.