【问题标题】:SQLAlchemy automap backref errorSQLAlchemy 自动映射 backref 错误
【发布时间】:2018-03-27 22:05:18
【问题描述】:

我对 SQLAlchemy 自动映射和覆盖名称有很大的问题。 请看下面的代码:

from sqlalchemy import create_engine, text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.automap import automap_base
import re
import inflect
import warnings
from sqlalchemy import inspect

#name overriding
def name_for_scalar_relationship(base, local_cls, referred_cls, constraint):
    name = referred_cls.__name__.lower()
    local_table = local_cls.__table__
    if name in local_table.columns:
        newname = name + "_"
        warnings.warn(
            "Already detected name %s present.  using %s" %
            (name, newname))
        return newname
    return name

def camelize_classname(base, tablename, table):
    "Produce a 'camelized' class name, e.g. "
    "'words_and_underscores' -> 'WordsAndUnderscores'"

    return str(tablename[0].upper() + \
            re.sub(r'_([a-z])', lambda m: m.group(1).upper(), tablename[1:]))

_pluralizer = inflect.engine()
def pluralize_collection(base, local_cls, referred_cls, constraint):
    "Produce an 'uncamelized', 'pluralized' class name, e.g. "
    "'SomeTerm' -> 'some_terms'"

    referred_name = referred_cls.__name__
    uncamelized = re.sub(r'[A-Z]',
                         lambda m: "_%s" % m.group(0).lower(),
                         referred_name)[1:]
    pluralized = _pluralizer.plural(uncamelized)
    return pluralized


engine = create_engine(
    "mysql+pymysql://blablabla@blabla/blabla", convert_unicode=True)

db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
#Mapping
Base = automap_base()
Base.prepare(engine, reflect=True, name_for_scalar_relationship = name_for_scalar_relationship, classname_for_table=camelize_classname, name_for_collection_relationship=pluralize_collection)

我使用了文档建议的所有覆盖函数,但仍然出现此错误:

sqlalchemy.exc.ArgumentError: Error creating backref 'order_supplier_rows' on relationship 'OrderSupplierRow.detail': property of that name exists on mapper 'Mapper|Detail|detail'

问题与上一篇文章中的相同: sqlalchemy Error creating backref on relationship

除非我无法更改数据库定义以重命名反向引用。或者这将是最后的解决方案,如果没有其他工作... 如果它们在自动映射期间已经存在多次,我想覆盖这些反向引用名称。

我已经尝试解决这个问题好几个小时了! 提前致谢!

【问题讨论】:

  • 您能否提供具体的表作为 SQL DDL 和一般的minimal reproducible example,可以用来重现您的问题。请记住将其保持在最低限度。它不必是您当前的表等。
  • 已编辑(见最后,我链接了另一个非常相似的帖子)
  • 所以OrderSupplierRowDetail 有多个外键关系?如果您提供要映射的表或重现错误的类似物,所有这一切都会容易得多。

标签: python sqlalchemy


【解决方案1】:

似乎我通过覆盖 backrefs 命名解决了这个问题:

def _gen_relationship(base, direction, return_fn,
                                attrname, local_cls, referred_cls, **kw):
    return generate_relationship(base, direction, return_fn,
                                 attrname+'_ref', local_cls, referred_cls, **kw)

打电话之前

Base.prepare(engine, reflect=True, generate_relationship=_gen_relationship)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-06
  • 2020-01-14
相关资源
最近更新 更多