获得现有表使用SQLAlchemy MetaD

2024-05-23 14:47:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个已经存在的表:

USERS_TABLE = Table("users", META_DATA,
                    Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
                    Column("first_name", String(255)),
                    Column("last_name", String(255))
                   )

我通过运行以下命令创建了此表:

CONN = create_engine(DB_URL, client_encoding="UTF-8")
META_DATA = MetaData(bind=CONN, reflect=True)
# ... table code
META_DATA.create_all(CONN, checkfirst=True)

第一次工作时,我就可以创建表了。然而,第二次我犯了这个错误:

sqlalchemy.exc.InvalidRequestError: Table 'users' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

这是有意义的,因为表users已经存在。我能看到这张桌子是否是这样存在的:

TABLE_EXISTS = CONN.dialect.has_table(CONN, "users")

但是,如何实际获取现有表对象?我在文件里找不到这个。请帮忙。


Tags: nameidtruedatastringcreatetablecolumn
3条回答

我们有三种不同的方法:

  • 假设已经创建了所需的表,反映它们并使用^{}字典字段

    from sqlalchemy import MetaData, create_engine
    
    CONN = create_engine(DB_URL, client_encoding="UTF-8")
    
    META_DATA = MetaData(bind=CONN, reflect=True)
    
    USERS_TABLE = META_DATA.tables['users']
    
  • 正在从^{}对象初始化中删除^{}标志,因为我们不使用它,而且-正在尝试创建已反映的表:

    from sqlalchemy import MetaData, Table, Column, Integer, String, Sequence, create_engine
    
    CONN = create_engine('sqlite:///db.sql')
    
    META_DATA = MetaData(bind=CONN)
    
    USERS_TABLE = Table("users", META_DATA,
                        Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
                        Column("first_name", String(255)),
                        Column("last_name", String(255))
                        )
    
    META_DATA.create_all(CONN, checkfirst=True)
    
  • 假设我们保留反射表,如果它以前是通过将^{}对象初始值设定项^{}标志设置为True创建的:

    from sqlalchemy import MetaData, Table, Column, Integer, String, Sequence, create_engine
    
    CONN = create_engine('sqlite:///db.sql')
    
    META_DATA = MetaData(bind=CONN, reflect=True)
    
    USERS_TABLE = Table("users", META_DATA,
                        Column("id", Integer, Sequence("user_id_seq"), primary_key=True),
                        Column("first_name", String(255)),
                        Column("last_name", String(255)),
                        keep_existing=True
                        )
    
    META_DATA.create_all(CONN, checkfirst=True)
    

选择哪一个?取决于您的用例,但我更喜欢第二个,因为看起来您没有使用反射,而且它是最简单的修改:只是从MetaData初始值设定项中删除标志。


P、 S.

我们总是可以在初始化MetaData对象后使用^{}方法进行反射:

META_DATA.reflect()

我们还可以指定用^{}参数(可以是^{}对象中的任何iterable)反映哪些表:

META_DATA.reflect(only=['users'])

以及many more

我试图单独使用checkfirst=True,但发现在它停止给我sqlalchemy.exc.InvalidRequestError之前,我还必须添加extend_existing

        metaData = MetaData(bind=engine, reflect=True)  

        with engine.connect() as connection:

            for dataItem in dataItemList:
                metaData.reflect()
                db.Table('roles_users',
                db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
                db.Column('role_id', db.Integer(), db.ForeignKey('role.id')),
                Column("data_value", String(255)),
                extend_existing=True)
                metaData.create_all(connection, checkfirst=True)  
__table_args__ = {'extend_existing': True}

就在__tablename__下面

相关问题 更多 >