On 10/13/2016 02:13 AM, Eric wrote:
Hi,
I have a models.py file where I'd like to define all the table classes
and then interact with them from my main module file (desktop app).  I
am connecting to Postgres 9.5 and have attached another Postgres
database on the same server (localhost) with postgres_fdw.  It all
appears to be working well, print(insp.get_foreign_table_names()) shows
the attached tables.  This is with Python 3.5.2 on Windows 7.

I am using DeferredReflection so I don't have to have the engine setup
in the model file and am connecting to one of the foreign tables:

    BaseDef = declarative_base(cls=DeferredReflection)
    class TestTable(BaseDef):
        __tablename__ = 'test_table'

and get the error when I run BaseDef.prepare(engine):
sqlalchemy.exc.ArgumentError: Mapper Mapper|TestTable|test_table could
not assemble any primary key columns for mapped table 'test_table'


I tried:

    class TestTable(BaseDef):
        __tablename__ = 'test_table'
        Column('test_id', Integer, primary_key=True)  # no effect

TestTable is a class definition, so everything inside of it has to be in the form of "key = value", including the columns (assuming they aren't further inside the constructor of a Table()):

class MyTable(Base):
    __tablename__ = 'foo'

    my_id = Column('my_id', Integer, primary_key=True)

I pulled out the adaptation of foriegn tables from the test suite and this use case works, e.g. with the PK inside the mapping only. see below.

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection

import sqlalchemy as sa

metadata = MetaData()

dblink = 'localhost'
e = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
for ddl in [
    "CREATE SERVER test_server FOREIGN DATA WRAPPER postgres_fdw "
    "OPTIONS (dbname 'test', host '%s')" % dblink,
    "CREATE USER MAPPING FOR public \
    SERVER test_server options (user 'scott', password 'tiger')",
    "CREATE FOREIGN TABLE test_foreigntable ( "
    "   id          INT, "
    "   data        VARCHAR(30) "
    ") SERVER test_server OPTIONS (table_name 'testtable')",
]:
    sa.event.listen(metadata, "after_create", sa.DDL(ddl))

for ddl in [
    'DROP FOREIGN TABLE test_foreigntable',
    'DROP USER MAPPING FOR public SERVER test_server',
    "DROP SERVER test_server"
]:
    sa.event.listen(metadata, "before_drop", sa.DDL(ddl))


Base = declarative_base()


class A(DeferredReflection, Base):
    __tablename__ = 'test_foreigntable'
    id = Column(Integer, primary_key=True)

metadata.create_all(e)
try:
    DeferredReflection.prepare(e)
finally:
    metadata.drop_all(e)




    and
    __mapper_args__ = {
        'primary_key': (test_table.c.test_id, )}  # attribute error on
test_id
Can I use DeferredReflection and still define the primary key column?

Also, any issue with defining some of the classes using a normal Base =
declarative_base() and some with deferred?  I'm using the normal Base
with classes where the full table definition is in the model file.  I'm
just starting to work with SQLAlchemy and Postgres after mostly working
with SQLite (and I'm a hardware guy).

Thanks,
Eric

--
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to sqlalchemy+unsubscr...@googlegroups.com
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to