emmett-framework / emmett

The web framework for inventors
Other
1.04k stars 70 forks source link

POSTGRES relation emmett_schema does not exist #301

Closed philmade closed 3 years ago

philmade commented 3 years ago

Following the tutorial I tried to setup Emmett with postgres - when I try do the migrations, I get this log from postgres; ERROR: relation "emmett_schema" does not exist at character 22

The actual migration code - but generating and up seem to work quite successfully.

gi0baro commented 3 years ago

Hi @NomeChomsky, I'm not sure I got it. Can you provide a bit of context regarding your issue? In particular would be helpful:

Also, a traceback of the error would be nice

philmade commented 3 years ago
version: "3"

services:
  postgres:
    image: postgres:11
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    env_file:
      - .env
    ports:
      - "5432:5432"
    command: postgres -c listen_addresses='*'
volumes:
  postgres_data:
# -*- coding: utf-8 -*-

from emmett import App, session, now, url, redirect, abort
from emmett.orm import Database, Model, Field, belongs_to, has_many
from emmett.tools import requires
from emmett.tools.auth import Auth, AuthUser
from emmett.sessions import SessionManager
from config import settings

app = App(__name__)
app.config.auth.single_template = True
app.config.auth.registration_verification = False
app.config.auth.hmac_key = "november.5.1955"

#: define models
class User(AuthUser):
    # will create "auth_user" table and groups/permissions ones
    has_many('posts', 'comments')

class Post(Model):
    belongs_to('user')
    has_many('comments')

    title = Field()
    text = Field.text()
    date = Field.datetime()

    default_values = {
        'user': lambda: session.auth.user.id,
        'date': now
    }
    validation = {
        'title': {'presence': True},
        'text': {'presence': True}
    }
    fields_rw = {
        'user': False,
        'date': False
    }

class Comment(Model):
    belongs_to('user', 'post')

    text = Field.text()
    date = Field.datetime()

    default_values = {
        'user': lambda: session.auth.user.id,
        'date': now
    }
    validation = {
        'text': {'presence': True}
    }
    fields_rw = {
        'user': False,
        'post': False,
        'date': False
    }

#: init db and auth
app.config.db.uri = settings.SQLALCHEMY_DATABASE_URI
db = Database(app)
auth = Auth(app, db, user_model=User)
db.define_models(Post, Comment)

#: setup helping function
def setup_admin():
    with db.connection():
        # create the user
        user = User.create(
            email="doc@emmettbrown.com",
            first_name="Emmett",
            last_name="Brown",
            password="fluxcapacitor"
        )
        # create an admin group
        admins = auth.create_group("admin")
        # add user to admins group
        auth.add_membership(admins, user.id)
        db.commit()

@app.command('setup')
def setup():
    setup_admin()

#: pipeline
app.pipeline = [
    SessionManager.cookies('GreatScott'), db.pipe, auth.pipe
]

#: exposing functions
@app.route("/")
async def index():
    posts = Post.all().select(orderby=~Post.date)
    return dict(posts=posts)

@app.route("/post/<int:pid>")
async def one(pid):
    def _validate_comment(form):
        # manually set post id in comment form
        form.params.post = pid
    # get post and return 404 if doesn't exist
    post = Post.get(pid)
    if not post:
        abort(404)
    # get comments and create a form for commenting
    comments = post.comments(orderby=~Comment.date)
    form = await Comment.form(onvalidation=_validate_comment)
    if form.accepted:
        redirect(url('one', pid))
    return locals()

@app.route("/new")
@requires(lambda: auth.has_membership('admin'), url('index'))
async def new_post():
    form = await Post.form()
    if form.accepted:
        redirect(url('one', form.params.id))
    return dict(form=form)

auth_routes = auth.module(__name__)

emmett migrations generate -m "first migration"

Generated migration for revision 29b7f674b5a8 emmet migrations up Generated migration for revision 29b7f674b5a8 Succesfully upgraded to revision 29b7f674b5a8: First migration emmet setup no output.

On docker-compose postgres log I get no readouts other than:

ERROR:  relation "emmett_schema" does not exist at character 22
postgres_1  | 2020-12-11 12:39:19.873 UTC [73] STATEMENT:  SELECT count(*) FROM "emmett_schema" WHERE ("emmett_schema"."id" > 0);

I lost the proper traceback as I moved on. I followed the bloggy tutorial. I changed the DB uri for postgres, and it seemed to work/connect but then nothing entered the database. I am running WSL (Ubuntu) on windows. I've copy pasted the code from the bloggy repo and chanaged app.config.db.uri to postgres, and it didn't seem to work correctly.

gi0baro commented 3 years ago

@NomeChomsky the error you see on the postgres container is normal, since the first time you run migrations it checks the schema version, and if the table doesn't exists it will create it.

I'm still quite confused about your issue: considering the migration were applied successfully, the setup run correctly, and the container logs the connections, you should be able at least to see the tables and the default user in the database. Sounds like a configuration issue to me. Also, in case the tables won't existed, launching the application should definitely raise an error with a traceback about the problem.

philmade commented 3 years ago

It says the migrations were applied successfully but I can't access the tables in the db. If I do User.create(email='foo') I get this:


"users"."updated_at", "users"."email", "users"."password",
"users"."registration_key", "users"."reset_password_key",
"users"."registration_id", "users"."first_name", "users"."last_name" FROM
"users" WHERE (("users"."id" IS NOT NULL) AND ("users"."email" = 'philly'))
ORDER BY "users"."id" LIMIT 1 OFFSET 0;```

the migrations script appears to run correctly, and the 'setup' script also
throws an error:
AttributeError: 'NoneType' object has no attribute 'users'

On Fri, Dec 11, 2020 at 10:52 PM Giovanni Barillari <
notifications@github.com> wrote:

> @NomeChomsky <https://github.com/NomeChomsky> the error you see on the
> postgres container is normal, since the first time you run migrations it
> checks the schema version, and if the table doesn't exists it will create
> it.
>
> I'm still quite confused about your issue: considering the migration were
> applied successfully, the setup run correctly, and the container logs the
> connections, you should be able at least to see the tables and the default
> user in the database. Sounds like a configuration issue to me. Also, in
> case the tables won't existed, launching the application should definitely
> raise an error with a traceback about the problem.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/emmett-framework/emmett/issues/301#issuecomment-743321696>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ALDN7X2FGNGAFAYU3SIB5N3SUJILPANCNFSM4UWPUKYQ>
> .
>
philmade commented 3 years ago
(Pdb) app.pipeline
[<emmett.sessions.CookieSessionPipe object at 0x7f3d4eab6bb0>, <emmett.orm.base.DatabasePipe object at 0x7f3d4eabf910>, <emmett.tools.auth.apis.AuthPipe object at 0x7f3d4eab6b50>]
(Pdb) db
<DAL uri="postgres:******@localhost:5432/signally">
(Pdb) user = User.create(email='foo')
*** ValueError: SELECT "users"."id", "users"."created_at", "users"."updated_at", "users"."email", "users"."password", "users"."registration_key", "users"."reset_password_key", "users"."registration_id", "users"."first_name", "users"."last_name" FROM "users" WHERE (("users"."id" IS NOT NULL) AND ("users"."email" = 'foo')) ORDER BY "users"."id" LIMIT 1 OFFSET 0;
(Pdb) 
philmade commented 3 years ago

Its strange because I can even put an endpoint in the app which returns a user object, but the object doesn't seem to be in the database. This does return - but only a str representation of the object

@app.route("/<str:username>")
async def make(username):
    user = User.create(email=username, first_name=username,
                       last_name='helloooo')
    db.commit()
    return dict(user=user)

this raises an attribute error

@app.route("/<str:username>")
async def make(username):
    user = User.create(email=username, first_name=username,
                       last_name='helloooo')
    db.commit()
    return dict(user=user.first_name)
gi0baro commented 3 years ago

@NomeChomsky I made a local test, and I experience no issues at all.

compose file:

version: '3.7'

services:
  db:
    image: postgres:11
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: bloggy
    ports:
      - "5432:5432"

setup:

bloggy ❯ emmett migrations up
> Performing upgrades against postgres://postgres:postgres@localhost:5432/bloggy
> Performing upgrade: <base> -> 9d6518b3cdc2 (head), First migration
> Adding revision 9d6518b3cdc2 to schema
> Succesfully upgraded to revision 9d6518b3cdc2: First migration
bloggy ❯ emmett setup

check:

bloggy ❯ emmett shell
Python 3.8.6 (default, Nov 24 2020, 00:25:15)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Emmett 2.1.4 shell on app: app
>>> db
<DAL uri="postgres:******@localhost:5432/bloggy">
>>> User.all().count()
1
>>> User.first()
<Row {'id': 1, 'created_at': datetime.datetime(2020, 12, 15, 16, 57, 22), 'updated_at': datetime.datetime(2020, 12, 15, 16, 57, 22), 'email': 'doc@emmettbrown.com', 'password': "pbkdf2(2000,20,sha512)$a0a797086c733cf0$b'f3eb9db1750cbb5f4044ffabdc98bf80d0661950'", 'registration_key': '', 'reset_password_key': '', 'registration_id': '', 'first_name': 'Emmett', 'last_name': 'Brown'}>
gi0baro commented 3 years ago

@NomeChomsky gonna close this due to inactivity, comment here in case you still need support