在SQLAlchemy中创建表时可以避免使用primary_key吗?

问题描述 投票:0回答:1

我有一个包含一堆巨大表的数据库,我想

  1. 使用 SQLAlchemy 与这些表交互
  2. 在本地sqlite数据库中创建类似的表(有几行)用于测试
  3. 针对 sqlite 表测试 SQLAlchemy 查询以进行单元测试

所以我发现可以通过以下方式从远程表获取元数据:

# Imports
from sqlalchemy import create_engine, Table, MetaData

# Creating engine for interacting with db
engine = create_engine("mssql+pyodbc://my_server/my_database?trusted_connection=yes&driver=my_driver")

# Fetching table metadata
metadata = MetaData()
my_table = Table("my_table", 
                 metadata, 
                 schema="my_database.my_schema",
                 autoload_with=engine)

# Listing columns, their types and settings
list(table.columns)

实际上,我希望这个表的定义存在于 Python 中,这样我的单元测试就不依赖于连接到远程数据库。所以我尝试在 SQLAlchemy 中构建它。

# Imports
from sqlalchemy.dialects.mssql import DATE, VARCHAR, TINYINT

# Declaring base
Base = declarative_base()

# Constructing table
class MyTable(Base):
    __tablename__ = 'my_table'

    col1= Column('col1', DATE(), nullable=False),
    col2= Column('col2', VARCHAR(length=15), nullable=False),
    col3= Column('col3', TINYINT(), nullable=False)

当我使用与上面标识的类型相同的类型构建表时,出现以下错误:

ArgumentError: Mapper mapped class Targets->my_table could not assemble any primary key columns for mapped table 'my_table'

显然,如果您自己构建表,SQLAlchemy ORM 要求表有一个primary_key。但是我想要“镜像”的表在数据库中没有primary_key,由于公司的组织和设置,这是我无法更改的。

是否有更智能的方法来构造具有相同类型的表?

python sql-server sqlite sqlalchemy
1个回答
0
投票

正如@snakecharmerb 所提到的,答案可以在文档的以下部分找到。有两种选择:

选项1

这里我们不使用ORM,我们只使用Table。

# Constructing table
my_table = Table(
    __tablename__ = 'my_table'

    Column('col1', DATE(), nullable=False),
    Column('col2', VARCHAR(length=15), nullable=False),
    Column('col3', TINYINT(), nullable=False)

    autoload=True, 
    autoload_with=engine,
    schema='my_schema'
)

选项2

如果存在使用declarative_base,可以执行以下操作

# Constructing table
my_table = Table(
    __tablename__ = 'my_table'

    Column('col1', DATE(), nullable=False),
    Column('col2', VARCHAR(length=15), nullable=False),
    Column('col3', TINYINT(), nullable=False)
    UniqueConstraint("col1", "col2", "col3")

    autoload=True, 
    autoload_with=engine,
    schema='my_schema'
)

# Constructing base class
class MyTable(Base):
    __tablename__ = 'my_table'
    __mapper_args__ = {"primary_key": [my_table.c.col1, my_table.c.col2, my_table.c.col3]}
© www.soinside.com 2019 - 2024. All rights reserved.