如何使用SQLAlchemy定义没有主键的表?

时间:2015-12-15 07:24:52

标签: python 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'.

如何丢失每个表必须有主键的约束?

6 个答案:

答案 0 :(得分:15)

我知道只有一种方法可以规避SQL Alchemy中的主键约束 - 它将特定列或列作为主键映射到您的表中,即使它们不是主键也是如此关键自己。 http://docs.sqlalchemy.org/en/latest/faq/ormconfiguration.html#how-do-i-map-a-table-that-has-no-primary-key

答案 1 :(得分:1)

没有适当的解决方案,但是有解决方法:

解决方法1

将参数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

解决方法2

只需在 ORM层而不是实际的数据库中声明一个新的哑列。只需在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

答案 2 :(得分:1)

免责声明:仅Oracle

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

答案 3 :(得分:1)

这是一个使用 __mapper_args__a synthetic 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]
    }

答案 4 :(得分:0)

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))

答案 5 :(得分:-1)

我找到的解决方案是将一个自动递增的主键列添加到表中,然后将其用作主键。数据库应该处理除此之外的所有其他事情。