8

我们通常什么时候在 SQLAlchemy 中得到以下错误?

sqlalchemy.exc.OperationalError: (OperationalError) (1050, "Table 'foobar' already exists")

foobar表确实已经存在,但是为什么 SQLAlchemy 在已经存在时尝试创建表。如果已经存在,我假设它不应该创建表。

我正在使用以下语法创建表:

t = Table('foobar', metadata,
      Column('col1', String(50), primary_key=True),
      Column('col2', String(100)),
      mysql_engine='InnoDB',
      mysql_charset='utf8')

(我并行调用同一个程序 10 次)

4

4 回答 4

20

只需使用带有checkfirst=True关键字的模式对象(表、索引和序列) 创建删除方法,表将自动添加适合 SQL的“IF NOT EXISTS 或 IF EXISTS CLAUSE” 。

例如:

t = Table('foobar', metadata,
  Column('col1', String(50), primary_key=True),
  Column('col2', String(100)),
  mysql_engine='InnoDB',
  mysql_charset='utf8')

t.create(checkfirst=True)
于 2013-04-14T19:00:15.787 回答
3

如果 foobar 表已经存在,您可以这样做:

users = Table('foobar', metadata, autoload=True)

SQLAlchemy 会自动从数据库中找出表的结构。

首先使用自动加载检查表是否存在,如果不存在则创建表。

于 2012-08-10T11:23:53.077 回答
1

这是我的一些故障排除想法的猜测。我的猜测是客户端认为该表不存在,因为它看不到它,但是在尝试创建它时,不能,因为它实际上确实存在。

故障排除思路:

  • 检查代码的其他部分是否正在写入同一个日志文件或其他任何内容,并尝试创建这些表。
  • 手动用和客户端一样的ID和密码登录,看看能不能看到表。
  • 传递echo=Truecreate_engine以了解客户端执行的确切查询,然后在您自己的 SQL shell 中重复所有查询以查看客户端所看到的内容。希望这会让你得出一个结论。
于 2012-08-10T15:01:03.250 回答
1

另一种选择是使用元数据:

database_engine = create_engine(
    'mssql+pyodbc://username:password=@server:1433/databaseName?driver=ODBC+Driver+17+for+SQL+Server?trusted_connection=no')
with database_engine.connect() as database_connection:
    metaData = MetaData(bind=database_engine, reflect=True)
    metaData.reflect()

    try:
        Table("tbl_stuff",
              metaData,
              Column("id", Integer, primary_key=True, autoincrement=False),
              Column("Name", String(255)),
              extend_existing=True)
        metaData.create_all(database_connection, checkfirst=True)
        metaData.reflect()
    except Exception as an_exc:
        logging.exception("Exception creating tbl_stuff: " + str(an_exc))

有关详细信息,请参阅https://docs.sqlalchemy.org/en/13/core/metadata.html

于 2019-12-19T18:11:39.543 回答