【问题标题】:Create a model with a foreign key to a table not created by SQLAlchemy使用不是由 SQLAlchemy 创建的表的外键创建模型
【发布时间】:2021-03-10 16:34:57
【问题描述】:

我的烧瓶应用程序有一个我使用 mysqlconnector 创建的表:

import mysql.connector
from .config import host, user, passwd, db_name

connection_pool = mysql.connector.pooling.MySQLConnectionPool(
    pool_size=8,
    host=host,
    user=user,
    password=passwd,
    database=db_name)
connection_object = connection_pool.get_connection()
cursor = connection_object.cursor(buffered=True)

cursor.execute(
            """CREATE TABLE IF NOT EXISTS MyTable (
                ID INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(255) NOT NULL UNIQUE
            )"""
connection_object.commit()

我正在导入的库 (authlib) 使用 SQL 连接到同一个数据库

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

from authlib.integrations.sqla_oauth2 import OAuth2ClientMixin

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqlconnector://user:pwd@host/db'
db = SQLAlchemy (app)

class OAuth2Client(db.Model, OAuth2ClientMixin):
    __tablename__ = 'oauth2_client'

    id = db.Column(db.Integer, primary_key=True)
    smthg_id = db.Column(
        db.Integer, db.ForeignKey('MyTable.id', ondelete='CASCADE'))
    smthg = db.relationship('MyTable')

client = OAuth2Client()
db.session.add (client)
db.session.commit()

在执行期间,它会引发此错误:

sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class OAuth2Client->oauth2_client, expression 'MyTable' failed to locate a name ("name 'MyTable' is not defined"). If this is a class name, consider adding this relationship() to the <class '__main__.OAuth2Client'> class after both dependent classes have been defined.

如何在 SQL Alchemy 中创建包含此类外键的表?

【问题讨论】:

  • 解决方案是不使用 SqlAlchemy 创建外键,而是使用原始的“ALTER TABLE”SQL 查询添加它们

标签: mysql flask sqlalchemy flask-sqlalchemy mysql-connector


【解决方案1】:

您可以使用 SQLAlchemy 的 reflection 功能为现有类创建 Table 实例,然后将该实例分配给模型的 __table__ 属性:

import sqlalchemy as sa

...

# Load the existing table into the db object's metadata
mytable = sa.Table('MyTable', db.metadata, autoload_with=db.engine)


# Create a model over the table.
class MyTable(db.Model):
    __table__ = mytable

现在可以从OAuth2Client 模型中成功引用MyTable

【讨论】:

  • 我很确定 autoload=True 现在已被认为已过时,而只需 autoload_with=db.engine 就足够了。
  • @GordThompson 你说的很对,autoload_with 就足够了,autoload 在 1.4 中已被弃用(尽管它仍然出现在 docs 的示例中
  • 感谢您的提醒。我已经提交了patch 来更新文档。
猜你喜欢
  • 2010-11-23
  • 2015-03-18
  • 1970-01-01
  • 2015-05-20
  • 1970-01-01
  • 1970-01-01
  • 2019-03-13
  • 2021-10-30
  • 2014-11-09
相关资源
最近更新 更多