Hi Mike,
The message has been truncated.

The CREATE TABLE statements is :
CREATE TABLE users (
        id BIGSERIAL NOT NULL,
        email VARCHAR(100) NOT NULL,
        name VARCHAR(100) NOT NULL,
        hashed_password VARCHAR(100) NOT NULL,
        is_admin BOOLEAN,
        is_active BOOLEAN,
        created TIMESTAMP WITHOUT TIME ZONE,
        modified TIMESTAMP WITHOUT TIME ZONE,
        PRIMARY KEY (id),
        UNIQUE (email)
)

CREATE TABLE permissions (
        id BIGSERIAL NOT NULL,
        name VARCHAR(100) NOT NULL,
        description VARCHAR(255),
        PRIMARY KEY (id),
        UNIQUE (name)
)

CREATE TABLE roles (
        id BIGSERIAL NOT NULL,
        name VARCHAR(100) NOT NULL,
        PRIMARY KEY (id),
        UNIQUE (name)
)

CREATE TABLE users_roles (
        users_id BIGINT NOT NULL,
        roles_id BIGINT NOT NULL,
        PRIMARY KEY (users_id, roles_id),
        FOREIGN KEY(users_id) REFERENCES users (id),
        FOREIGN KEY(roles_id) REFERENCES roles (id)
)

CREATE TABLE roles_permissions (
        roles_id BIGINT NOT NULL,
        permissions_id BIGINT NOT NULL,
        PRIMARY KEY (roles_id, permissions_id),
        FOREIGN KEY(roles_id) REFERENCES roles (id),
        FOREIGN KEY(permissions_id) REFERENCES permissions (id)
)

CREATE TABLE users_permissions (
        users_id BIGINT NOT NULL,
        permissions_id BIGINT NOT NULL,
        PRIMARY KEY (users_id, permissions_id),
        FOREIGN KEY(users_id) REFERENCES users (id),
        FOREIGN KEY(permissions_id) REFERENCES permissions (id)
)

My mistake is to have mixed in my mind the information of the object
mapping and the relational constraints of the database.
But why Alembic can’t create this model in auto-generation mode?

Best regards

Le jeu. 13 déc. 2018 à 18:12, patrick payet <papa...@gmail.com> a écrit :

>         PRIMARY KEY (id),
>         UNIQUE (email)
> )
>
> CREATE TABLE permissions (
>         id BIGSERIAL NOT NULL,
>         name VARCHAR(100) NOT NULL,
>         description VARCHAR(255),
>         PRIMARY KEY (id),
>         UNIQUE (name)
> )
>
> CREATE TABLE roles (
>         id BIGSERIAL NOT NULL,
>         name VARCHAR(100) NOT NULL,
>         PRIMARY KEY (id),
>         UNIQUE (name)
> )
>
> CREATE TABLE users_roles (
>         users_id BIGINT NOT NULL,
>         roles_id BIGINT NOT NULL,
>         PRIMARY KEY (users_id, roles_id),
>         FOREIGN KEY(users_id) REFERENCES users (id),
>         FOREIGN KEY(roles_id) REFERENCES roles (id)
> )
>
> CREATE TABLE roles_permissions (
>         roles_id BIGINT NOT NULL,
>         permissions_id BIGINT NOT NULL,
>         PRIMARY KEY (roles_id, permissions_id),
>         FOREIGN KEY(roles_id) REFERENCES roles (id),
>         FOREIGN KEY(permissions_id) REFERENCES permissions (id)
> )
>
> CREATE TABLE users_permissions (
>         users_id BIGINT NOT NULL,
>         permissions_id BIGINT NOT NULL,
>         PRIMARY KEY (users_id, permissions_id),
>         FOREIGN KEY(users_id) REFERENCES users (id),
>         FOREIGN KEY(permissions_id) REFERENCES permissions (id)
> )
>
> My mistake is to have mixed in my mind the information of the object
> mapping and the relational constraints of the database.
> But why Alembic can’t create this model in auto-generation mode?
>
> Best regards
>
> Le jeu. 13 déc. 2018 à 14:44, Mike Bayer <mike...@zzzcomputing.com> a
> écrit :
>
>> On Thu, Dec 13, 2018 at 7:11 AM patrick payet <papa...@gmail.com> wrote:
>> >
>> > Hi Mike,
>> > Thanks for your answer.
>> > My problem it’s a classical problem for application development, I want
>> to make authentication and authorisation for a web application.
>> > I want to understand why Alembic can’t create the model in
>> autogeneration mode and how modify this model to resolve this problem.
>> > With this model I have a join table to provide a many-to-many
>> relationship between users and roles (users group) for example.
>> > This allows me to access all roles for one user. For this, I declare a
>> variable roles in users class and I want to make a foreign key with this
>> join table
>> > to reach the roles.
>> > This joins table has a composite primary key (users.id foreign key and
>> roles.id foreign key)  and I don’t know how to make the link (foreign
>> key) with alembic for the  users.roles and this composite primary key.
>>
>> the link is the user_roles table and the FOREIGN KEY constraints it
>> has between users and roles tables.     you can't locate a unique row
>> in user_roles given only the user table because it has no column that
>> refers to user_roles.roles_id.    at least I'm trying to parse your
>> words as given.  however CREATE TABLE statements will show exactly
>> what you mean in case it is something different that just happens to
>> sound the same when described.
>>
>> When I declare just one element of this primary key, I have the error
>> quoted previously ( there is no unique constraint matching given keys
>> for referenced table "users_roles").
>> > I will send you the CREATE TABLE statements by email in a moment.
>>
>> yup
>>
>>
>>
>> > Best regards,
>> > Patrick
>> >
>> > Le mer. 12 déc. 2018 à 19:40, Mike Bayer <mike...@zzzcomputing.com> a
>> écrit :
>> >>
>> >> On Wed, Dec 12, 2018 at 1:01 PM patrick payet <papa...@gmail.com>
>> wrote:
>> >> >
>> >> > I had a SQLAlchemy model like -
>> >> > <code>
>> >> > class User(DeclarativeBase):
>> >> >     __tablename__ = 'users'
>> >> >
>> >> >     id = Column(BigInteger, primary_key=True)
>> >> >     email = Column(String(100), unique=True, nullable=False)
>> >> >     name = Column(String(100), nullable=False)
>> >> >     hashed_password = Column(String(100), nullable=False)
>> >> >     is_admin = Column(BOOLEAN, default=False)
>> >> >     is_active = Column(BOOLEAN, default=True)
>> >> >     created = Column(DateTime, default=datetime.now)
>> >> >     modified = Column(DateTime, default=datetime.now,
>> onpudate=datetime.datetime.now)
>> >> >     roles = relationship('Role', secondary=users_roles,
>> back_populates='users', cascade="all, delete-orphan")
>> >> >     permissions = relationship('Permission',
>> secondary=users_permissions, back_populates='users',
>> >> >                                cascade="all, delete-orphan")
>> >> >
>> >> >     def __repr__(self):
>> >> >         return "<User(name='%s', email='%s', hashed_password='%s')>"
>> % (self.name, self.email, self.hashed_password)
>> >> >
>> >> >
>> >> > class Role(DeclarativeBase):
>> >> >     __tablename__ = 'roles'
>> >> >
>> >> >     id = Column(BigInteger, primary_key=True)
>> >> >     name = Column(String(100), unique=True, nullable=False)
>> >> >     users = relationship('User', secondary=users_roles,
>> back_populates='roles',cascade="all, delete-orphan")
>> >> >     permissions = relationship('Permission',
>> secondary=roles_permissions, back_populates='roles',
>> >> >                                cascade="all, delete-orphan")
>> >> >
>> >> >     def __repr__(self):
>> >> >         return "<Role(name='%s')>" % self.name
>> >> >
>> >> >
>> >> > class Permission(DeclarativeBase):
>> >> >     __tablename__ = 'permissions'
>> >> >
>> >> >     id = Column(BigInteger, primary_key=True)
>> >> >     name = Column(String(100), unique=True, nullable=False)
>> >> >     description = Column(String(255))
>> >> >     users = relationship('User', secondary=users_permissions,
>> back_populates='permissions',
>> >> >                          cascade="all, delete-orphan")
>> >> >     roles = relationship('Role', secondary=roles_permissions,
>> back_populates='permissions',
>> >> >                          cascade="all, delete-orphan")
>> >> >
>> >> >     def __repr__(self):
>> >> >         return "<Permission(name='%s', description='%s')>" % (
>> self.name, self.description)
>> >> > </code>
>> >> > However, Alembic is not generating the correct upgrade, i try to
>> make it
>> >> > <code>
>> >> >
>> >> > def upgrade():
>> >> >     # ### commands auto generated by Alembic - please adjust! ###
>> >> >     # op.drop_table('users')
>> >> >     # ### end Alembic commands ###
>> >> >
>> >> >     op.create_table('roles',
>> >> >                     sa.Column('id', sa.BIGINT(), autoincrement=True,
>> nullable=False),
>> >> >                     sa.Column('name', sa.String(100),
>> autoincrement=False, nullable=False),
>> >> >                     sa.Column('users', BigInteger),
>> >> >                     sa.Column('permissions', BigInteger),
>> >> >                     sa.PrimaryKeyConstraint('id'),
>> >> >                     sa.UniqueConstraint('name',
>> name='roles_name_key')
>> >> >                     # sa.ForeignKeyConstraint(['users'],
>> ['users_roles.users_id'], ondelete='CASCADE'),
>> >> >                     # sa.ForeignKeyConstraint(['permissions'],
>> ['roles_permissions.permissions_id'], ondelete='CASCADE')
>> >> >                     )
>> >> >     op.create_table('permissions',
>> >> >                     sa.Column('id', sa.BIGINT(), autoincrement=True,
>> nullable=False),
>> >> >                     sa.Column('name', sa.String(100),
>> autoincrement=False, nullable=False),
>> >> >                     sa.Column('description', sa.String(255)),
>> >> >                     sa.Column('users', BigInteger),
>> >> >                     sa.Column('roles', BigInteger),
>> >> >                     sa.PrimaryKeyConstraint('id')
>> >> >                     # sa.ForeignKeyConstraint(['users'],
>> ['users_permissions.users_id'], ondelete='CASCADE'),
>> >> >                     # sa.ForeignKeyConstraint(['roles'],
>> ['role_permissions.roles_id'], ondelete='CASCADE')
>> >> >                     )
>> >> >     op.create_table('users_roles',
>> >> >                     sa.Column('users_id', BigInteger, sa.ForeignKey('
>> users.id'), primary_key=True),
>> >> >                     sa.Column('roles_id', BigInteger, sa.ForeignKey('
>> roles.id'), primary_key=True)
>> >> >                     )
>> >> >     op.create_table('users_permissions',
>> >> >                     sa.Column('users_id', BigInteger, sa.ForeignKey('
>> users.id'), primary_key=True),
>> >> >                     sa.Column('permissions_id', BigInteger,
>> sa.ForeignKey('permissions.id'), primary_key=True)
>> >> >                     )
>> >> >     op.create_table('roles_permissions',
>> >> >                     sa.Column('roles_id', BigInteger, sa.ForeignKey('
>> roles.id'), primary_key=True),
>> >> >                     sa.Column('permissions_id', BigInteger,
>> sa.ForeignKey('permissions.id'), primary_key=True)
>> >> >                     )
>> >> >     op.drop_constraint('users_name_key', 'users')
>> >> >     op.add_column('users', sa.Column('is_admin', sa.BOOLEAN,
>> autoincrement=False, nullable=False, default=False))
>> >> >     op.add_column('users', sa.Column('is_active', sa.BOOLEAN,
>> autoincrement=False, nullable=False, default=True))
>> >> >     op.add_column('users', sa.Column('created', sa.DateTime,
>> autoincrement=False, nullable=False,
>> >> >                                      default=datetime.datetime.now))
>> >> >     op.add_column('users', sa.Column('modified', sa.DateTime,
>> autoincrement=False, nullable=False,
>> >> >                                      default=datetime.datetime.now))
>> >> >     op.add_column('users', sa.Column('roles', BigInteger))
>> >> >     op.add_column('users', sa.Column('permissions', BigInteger))
>> >> >
>> >> >     op.create_foreign_key(constraint_name="users_roles_fk",
>> source_table="users", referent_table="users_roles",
>> >> >                           local_cols=["roles"],
>> remote_cols=["roles_id"], ondelete='CASCADE')
>> >> >     op.create_foreign_key("users_permissions_fk", "users",
>> "users_permissions", ["permissions"], ["permissions_id"],
>> >> >                           ondelete='CASCADE')
>> >> >     op.create_foreign_key("permissions_users_fk", "permissions",
>> "users_permissions", ["users"], ["users_id"],
>> >> >                           ondelete='CASCADE')
>> >> >     op.create_foreign_key("permissions_roles_fk", "permissions",
>> "roles_permissions", ["roles"], ["roles_id"],
>> >> >                           ondelete='CASCADE')
>> >> >     op.create_foreign_key("roles_users_fk", "roles", "users_roles",
>> ["users"], ["users_id"],
>> >> >                           ondelete='CASCADE')
>> >> >     op.create_foreign_key("roles_permissions_fk", "roles",
>> "roles_permissions", ["permissions"], ["permissions_id"],
>> >> >                           ondelete='CASCADE')
>> >> > </code>
>> >> > i have an error, primary key for users_roles is a composite keys and
>> i dont know how declare it, how make that
>> >>
>> >> it's not clear here if you're saying alembic is adding foreign keys
>> >> where they dont belong during autogenerate, or if you dont know why
>> >> you are getting the error you are getting.  The error is because you
>> >> don't need FOREIGN KEY constraints on roles, permissions, or users -
>> >> the FOREIGN KEY is only on the many-to-many tables, in this case
>> >> users_roles, users_permissions, roles_permissions.
>> >>
>> >> otherwise if you can illustrate the exact CREATE TABLE statements
>> >> you'd like to see, I can illustrate a correct model for that which
>> >> Alembic will generate.
>> >>
>> >>
>> >>
>> >> > <code>
>> >> > sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) there
>> is no unique constraint matching given keys for referenced table
>> "users_roles"
>> >> >  [SQL: 'ALTER TABLE users ADD CONSTRAINT users_roles_fk FOREIGN
>> KEY(roles) REFERENCES users_roles (roles_id) ON DELETE CASCADE']
>> (Background on this error at: http://sqlalche.me/e/f405)
>> >> > </code>
>> >> >
>> >> > --
>> >> > You received this message because you are subscribed to the Google
>> Groups "sqlalchemy-alembic" group.
>> >> > To unsubscribe from this group and stop receiving emails from it,
>> send an email to sqlalchemy-alembic+unsubscr...@googlegroups.com.
>> >> > For more options, visit https://groups.google.com/d/optout.
>> >>
>> >> --
>> >> You received this message because you are subscribed to the Google
>> Groups "sqlalchemy-alembic" group.
>> >> To unsubscribe from this group and stop receiving emails from it, send
>> an email to sqlalchemy-alembic+unsubscr...@googlegroups.com.
>> >> For more options, visit https://groups.google.com/d/optout.
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> Groups "sqlalchemy-alembic" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> an email to sqlalchemy-alembic+unsubscr...@googlegroups.com.
>> > For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "sqlalchemy-alembic" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to sqlalchemy-alembic+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

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

Reply via email to