为什么print(myTable .__ table__)始终只打印__tablename__?

时间:2019-01-08 18:43:33

标签: python postgresql sqlalchemy

使用postgresql 11.1和python 3.6.7,在https://docs.sqlalchemy.org/en/rel_1_2/orm/tutorial.html上完成sqlalchemy orm教程

我已经创建了Users类,如代码所示。 当我尝试打印__table__成员时,似乎仅输出__tablename__成员,如下面的输出所示。有人可以帮我理解为什么吗?

当我在课堂上inspect.getmembers(Users) __table__代表正确。当我尝试print(Users.__table__)时,我始终只能获得__tablename__的值。

import inspect
import os
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy import Sequence
from sqlalchemy.orm import sessionmaker

myEngine = create_engine(os.getenv('DATABASE_URL'), echo=True)
mySession = sessionmaker(bind=myEngine)
myBase = declarative_base()

class User(myBase):
    __tablename__ = 'users'
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    name = Column(String(50))
    fullname = Column(String(50))
    password = Column(String(12))

    def __repr__(self):
        return "<User(name='%s', fullname='%s', password='%s')>" % (self.name, self.fullname, self.password)


print('User.__table__=', User.__table__)
print('User.__tablename__=', User.__tablename__)
print(inspect.getmembers(User))

输出:

User.__table__= users
User.__tablename__= users
[('__class__', <class 'sqlalchemy.ext.declarative.api.DeclarativeMeta'>), ('__delattr__', <slot wrapper '__delattr__' of 'object' objects>), ('__dict__', mappingproxy({'__module__': '__main__', '__tablename__': 'users', 'id': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4a40>, 'name': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4af0>, 'fullname': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4ba0>, 'password': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4c50>, '__repr__': <functionUser.__repr__ at 0x7f3824b0b598>, '__doc__': None, '__table__': Table('users', MetaData(bind=None), Column('id', Integer(), table=<users>, primary_key=True, nullable=False, default=Sequence('user_id_seq', metadata=MetaData(bind=None))), Column('name', String(length=50), table=<users>), Column('fullname', String(length=50), table=<users>), Column('password', String(length=12), table=<users>), schema=None), '_sa_class_manager': <ClassManager of <class '__main__.User'> at 7f3824af4990>, '__init__': <function __init__ at 0x7f3824b0b730>, '__mapper__': <Mapper at 0x7f3824b00da0; User>})), ('__dir__', <method '__dir__' of 'object' objects>), ('__doc__', None), ('__eq__', <slot wrapper '__eq__' of 'object' objects>), ('__format__', <method '__format__' of 'object' objects>), ('__ge__', <slot wrapper '__ge__' of 'object' objects>), ('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>), ('__gt__', <slot wrapper '__gt__' of 'object' objects>), ('__hash__', <slot wrapper '__hash__' of 'object' objects>), ('__init__', <function __init__ at 0x7f3824b0b730>), ('__init_subclass__', <built-in method __init_subclass__ of DeclarativeMeta object at 0x16ded08>), ('__le__', <slot wrapper '__le__' of 'object' objects>), ('__lt__', <slot wrapper '__lt__' of 'object' objects>), ('__mapper__', <Mapper at 0x7f3824b00da0; User>), ('__module__', '__main__'), ('__ne__', <slot wrapper '__ne__' of 'object' objects>), ('__new__', <built-in method __new__ of type object at 0x9d1260>), ('__reduce__', <method '__reduce__' of 'object' objects>), ('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>), ('__repr__', <function User.__repr__ at 0x7f3824b0b598>), ('__setattr__', <slot wrapper '__setattr__' of 'object' objects>), ('__sizeof__', <method '__sizeof__' of 'object' objects>), ('__str__', <slot wrapper '__str__' of 'object' objects>), ('__subclasshook__', <built-in method __subclasshook__ of DeclarativeMeta object at 0x16ded08>), ('__table__', Table('users', MetaData(bind=None), Column('id', Integer(), table=<users>, primary_key=True, nullable=False, default=Sequence('user_id_seq', metadata=MetaData(bind=None))), Column('name', String(length=50), table=<users>), Column('fullname', String(length=50), table=<users>), Column('password', String(length=12), table=<users>), schema=None)), ('__tablename__', 'users'), ('__weakref__', <attribute '__weakref__' of 'Base' objects>), ('_decl_class_registry', <WeakValueDictionary at 0x7f3824b5ec88>), ('_sa_class_manager', <ClassManager of <class '__main__.User'> at 7f3824af4990>), ('fullname', <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4ba0>), ('id', <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4a40>), ('metadata', MetaData(bind=None)), ('name', <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4af0>), ('password', <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x7f3824af4c50>)]

1 个答案:

答案 0 :(得分:0)

print()函数将使用Table函数将其参数(包括您的str()对象)转换为字符串。

str()对象上使用sqlalchemy.Table时,仅返回表名,这是设计使然。

metadata = sqlalchemy.MetaData()
t = sqlalchemy.Table('foo', metadata)
ts = str(t)
print(len(ts), repr(ts))

将打印

 3 'foo'

在您的inspect.getmembers()呼叫中,您会得到dict个成员,print()仍会呼叫str()dict转换为字符串,但是任何dict在转换时将在其内容中调用repr()

这意味着在这种情况下,您以表格的repr()结尾。

metadata = sqlalchemy.MetaData()
t = sqlalchemy.Table('foo', metadata)
ts = repr(t)
print(len(ts), repr(ts))

将打印

46 "Table('foo', MetaData(bind=None), schema=None)"

出于参考和完整性的考虑,以下是Table类定义的一部分relevant lines in sqlalchemy source code

def __repr__(self):
    return "Table(%s)" % ", ".join(
        [repr(self.name)]
        + [repr(self.metadata)]
        + [repr(x) for x in self.columns]
        + ["%s=%s" % (k, repr(getattr(self, k))) for k in ["schema"]]
    )

def __str__(self):
    return _get_table_key(self.description, self.schema)