[英]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.