akumoth/peewee-issues huggingface dataset:
Issue: How to do deferred engine selection?
Author: arnuschky
State: closed
Created: 2014-06-01 00:13:55

How can one do deferred engine selection?

For example, if I use a class similarly as `Database` of `flask-peewee`, I would like to select the engine/configure peewee after creation of the instance (ie, the commong `init_app()` approach). Unfortunately, all my models need to know their baseclass to reference the database. Is there any way around this? Can I change the database in the baseclass?

This is related to https://github.com/coleifer/flask-peewee/issues/69


I am now monkey-patching my models (see issue mentioned above). Would be great if we could come up with a less 'hacky' solutions, though.


Check out these docs: http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#dynamically-defining-a-database


Ah. D'oh. Thank you. Works like a charm.


Link http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#dynamically-defining-a-database doesn't exist anymore. Can you help?

* http://docs.peewee-orm.com/en/latest/peewee/database.html#run-time-database-configuration
* http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database

Thank you,

works very well!
Regards / Liebe Grüße,

Ralph Mueller

Annastrasse 44, 64673 Zwingenberg
Mobile: +49 177 449 0460
Office: +49 6251 789545
email: ralph.mueller.de@gmail.com <mailto:ralph.mueller.de@gmail.com>
https://www.ralph-mueller.net <https://www.ralph-mueller.net/>



> Am 15.03.2018 um 14:51 schrieb Charles Leifer <notifications@github.com>:
> 
> http://docs.peewee-orm.com/en/latest/peewee/database.html#run-time-database-configuration <http://docs.peewee-orm.com/en/latest/peewee/database.html#run-time-database-configuration>
> http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database <http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub <https://github.com/coleifer/peewee/issues/365#issuecomment-373382277>, or mute the thread <https://github.com/notifications/unsubscribe-auth/ADTj_Fu6e-McLX3HmyYyH7Pm9bsnFbHRks5tenHggaJpZM4CABL7>.
>
Issue: DISTINCT ON
Author: coleifer
State: closed
Created: 2014-05-28 18:54:13

First-class support for this feature.


I did a bit of digging and it looks like you can write:

```
SELECT DISTINCT(col1, col2), col1, ... FROM
```

So I'm going to close this since you can emulate this:

``` python
MyModel.select(fn.DISTINCT(MyModel.col1, MyModel.col2), MyModel.col1)...
```


Actually it turns out the semantics are a bit different... reopening.


Fixed by 19d2c2e738f874c
Issue: Created a new parameter 'reconnect' to indicate if MySQLAdapter can try ...
Author: andmart
State: closed
Created: 2014-05-28 12:42:52

Created a new parameter 'reconnect' to indicate if MySQLAdapter can try reconnect to server. 
In long time connections, timeout makes connection to drop.
I have an app that faces too many "MySQL server has gone away" errors. So, this can try reconnect to the server in case of timeout.


I am going to pass on this, but if you would like you can always subclass `MySQLDatabase` and implement this logic yourself. Catching `Exception` is far too broad and I believe this will lead to unpredictable behavior.


It's true. I created a MySQLWithReconnectDatabase and narrowed the exception to _mysql_exceptions.OperationalError error code 2006.

Thanks, Charles.


I actually like the idea of having it auto-reconnect on that error, I've
had the same issue before and fixed it by manually making a new connection
every time.

On Wed, May 28, 2014 at 10:56 PM, André Martins notifications@github.comwrote:

> It's true. I created a MySQLWithReconnectDatabase and narrowed the
> exception to _mysql_exceptions.OperationalError error code 2006.
> 
> Thanks, Charles.
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/coleifer/peewee/pull/363#issuecomment-44438590
> .


Perhaps this database subclass could go in `playhouse.mysql_ext`?


I think there is no need for auto-reconnect feature. 

The connection must be explicitly handled on every request by the developer of the app, not by peewee. That includes opening/closing it when needed.


> The connection must be explicitly handled on every request by the developer of the app, not by peewee. That includes opening/closing it when needed.

**Yes.**


I agree, but there is not a single point in code to handle this. Instead, every use of peewee can throw this error. How could separate responsabilities and use peewee with a datapool, for example?


In case you're interested, I've got a mixin for retrying failed queries in 017e4e4952f0b429dd21f0e90465a0f644cf6015 . Docs:

http://docs.peewee-orm.com/en/latest/peewee/database.html#automatic-reconnect
Issue: Having to declare database path as static global is harmful
Author: mchaput
State: closed
Created: 2014-05-27 20:01:13

It's a real problem for me that I have to hardcode the path to the database as a global. This basically makes it impossible to use peewee in a library where I expect to have the database path passed to me.

I can work around hardcoding the value by gymnastics stuffing a value into a global location before I import peewee, but it's still global so it's impossible to create two separate database instances using peewee (e.g. in a library or a blueprint).

I expected it to be possible to use peewee based on the database instance, e.g. something like:

``` python
class Page(Model):
    title = CharField()
    content = TextField()

def get_db(path):
    db = SqliteDatabase(path)
    db.create_table(Page)
    return db

def add_page(db, title, content):
    p = db.create(Page, title=title, content=content)
    p.save()
```

Is it possible I missed a way to use peewee similar to this? If the only way to use it is with globals, I don't think I can use peewee at all and I'll have to try something else.

Thanks.


Docs:
- http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#deferring-initialization
- http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#dynamically-defining-a-database

>  If the only way to use it is with globals, I don't think I can use peewee at all and I'll have to try something else.

To be honest, I don't want users with an attitude like yours.
Issue: test failures in -0.2.1; test_choices test_null_form_saving
Author: idella
State: closed
Created: 2014-05-25 03:11:34

tested under only py2.7.

``` python
======================================================
FAIL: test_choices (wtfpeewee.tests.WTFPeeweeTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/mnt/gen2/TmpDir/portage/dev-python/wtf-peewee-0.2.1/work/wtf-peewee-0.2.1/wtfpeewee/tests.py", line 162, in test_choices
    self.assertFalse(form.validate())
AssertionError: True is not false

=====================================================
FAIL: test_null_form_saving (wtfpeewee.tests.WTFPeeweeTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/mnt/gen2/TmpDir/portage/dev-python/wtf-peewee-0.2.1/work/wtf-peewee-0.2.1/wtfpeewee/tests.py", line 330, in test_null_form_saving
    self.assertEqual(nfm.b, True)
AssertionError: False != True

----------------------------------------------------------------------
Ran 13 tests in 0.058s

FAILED (failures=2)
```

Do you replicate? Do you require anything further.


The latest version, 0.2.3, is passing for me.


sorry, still get 1 fail;  Updated to peewee>=2.0.0, also wtforms.
$ python -V
Python 2.7.6

``` python
wtf-peewee-0.2.3 $ PYTHONPATH=. python ./runtests.py 
test_blog_form (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_blog_form_saving (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_blog_form_with_obj (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_choices (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_defaults (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_entry_form (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_entry_form_saving (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_entry_form_with_obj (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_form_multiple (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_form_with_only_exclude (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_hidden_field (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_hidden_field_none (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_non_int_pk (wtfpeewee.tests.WTFPeeweeTestCase) ... ok
test_null_form_saving (wtfpeewee.tests.WTFPeeweeTestCase) ... FAIL

======================================================================
FAIL: test_null_form_saving (wtfpeewee.tests.WTFPeeweeTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/mnt/gen2/TmpDir/portage/dev-python/wtf-peewee-0.2.3/work/wtf-peewee-0.2.3/wtfpeewee/tests.py", line 348, in test_null_form_saving
    self.assertEqual(nfm.b, True)
AssertionError: False != True

----------------------------------------------------------------------
Ran 14 tests in 0.097s

FAILED (failures=1)
```
Issue: Compiler interpolation
Author: oz123
State: closed
Created: 2014-05-23 13:12:56

Hi, 

I am trying to use peewee with cx_Oracle. So far with limited success. When I issue 

`inst.save()` it compiles an expression with `?`. e.g I have a model : 

```
  class TestDBOz(pw.BaseModel):
          sessionid = pw.IntegerField()
          action = pw.Charfield()

  sid=TestDbOz(sessionid=123, action='Test') 
  sid.save()
```

The above compiles to:

```
  'INSERT INTO "testdboz" ("sessionid", "action") VALUES (?, ?)', [123, Test])'
```

Which sadly, is not accepted by oracle. I was wondering if there is a quick way to replace interpolation with a function that yields a numeric interpolation:

```
 'INSERT INTO "testdboz" ("sessionid", "action") VALUES (:1, :2)', [123, Test])'
```


The `Database` class has an `interpolation` attribute which you could set:

``` python
class OracleDatabase(Database):
    interpolation = '%s'
```

Unfortunately there is no support for automatically numbering parameters. Will `%s` work?
Issue: peewee.IntegrityErro no fallback to update
Author: DarkRedman
State: closed
Created: 2014-05-19 03:09:43

When I read this section : http://peewee.readthedocs.org/en/latest/peewee/api.html?highlight=save#Model.save
I see the force_insert only work for the primary key, could it be updated to work with unique constraint too ?

For example if I create a sql object with a varchar field with unique constraint (and the has a duplicate) it should fallback to update to get the existing object and update it.


> could it be updated to work with unique constraint too?

That would be a couple line function to write, so I think I will leave it out of peewee for now.
Issue: Create a test_database
Author: jonathan-s
State: closed
Created: 2014-05-16 20:41:17

When you create a model, the database is tightly coupled with the model itself. When testing a model it doesn't seem to be possible to create a test_database which you then destroy at the end of the test. 


You have many options, actually. You can:
1. Set `ModelClass._meta.database` by hand, changing it to a test database.
2. Use a `Proxy` for your `Database` and initialize it with a different database when testing [how-to](http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#dynamically-defining-a-database).
3. Use an uninitialized `Database` and initialize it with a different db name [how-to](http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#deferring-initialization).
4. Use `test_utils.test_database` context manager. [how-to](http://peewee.readthedocs.org/en/latest/peewee/playhouse.html#test_database)


You can also create and drop tables.

``` python
from peewee import create_model_tables
from peewee import drop_model_tables

MODELS = [ModelA, ModelB, ...]

...
def setUp(self):
    create_model_tables(MODELS)

def tearDown(self):
    drop_model_tables(MODELS)
```


Thanks a lot! I'm still learning obviously. :)


> When you create a model, the database is tightly coupled with the model itself.

I understand, you just sounded like you were speaking from a point of authority.
Issue: Override 'AS' in 'FROM table AS t1'
Author: devsli
State: closed
Created: 2014-05-16 14:13:45

Seems like 'AS' is hardcoded [here](https://github.com/coleifer/peewee/blob/master/peewee.py#L1179). Is it possible to override it in database subclass?

Firebird [doesn't use](http://www.firebirdsql.org/refdocs/langrefupd21-select.html) 'AS' for aliases.

EDIT: worksforme in firebird2.5 test case, need clarification


Interesting, I think this should be fixable but will require a quick code change.

``` python
    def parse_node(self, node, alias_map=None, conv=None):
        sql, params, unknown = self._parse(node, alias_map, conv)
        if unknown and conv and params:
            params = [conv.db_value(i) for i in params]

        if isinstance(node, Node):
            if node._negated:
                sql = 'NOT %s' % sql
            if node._alias:
                sql = ' '.join((sql, 'AS', node._alias))
            if node._ordering:
                sql = ' '.join((sql, node._ordering))
        return sql, params
```

Alternatively, you could subclass `QueryCompiler` and specify it in your subclass of `Database` that uses firebird's driver.  Can you share your firebird db class, btw? I'd be interested in integrating it into the `playhouse` module.


Thank you for response! By the way, [my class](https://github.com/devsli/peewee-fdb/blob/master/peewee_fdb.py) is untidy now (I'm just learning Python). If you are interested, I'll let you know when it will become better.
Issue: Using PostgreSQL, Model.create() leaves connection idle in transaction
Author: gmcnutt
State: closed
Created: 2014-05-15 15:23:47

peewee==2.1.7
psycopg2==2.5.1
psql (9.3.4)
Python 3.4.0 (default, Apr 28 2014, 13:52:15) 

The following code snippet will reproduce it:

``` python
from peewee import *
db = PostgresqlDatabase('dbname', user='user', password='password',
                        host='localhost')
db.connect()

class Test(Model):
    class Meta:
        database = db
    pk = PrimaryKeyField()
    val = IntegerField()
```

Test.create_table(fail_silently=True)
Test.create(val=1)

The postgresql log shows this:

2014-05-15 09:14:50 MDT LOG:  statement: COMMIT
2014-05-15 09:14:54 MDT LOG:  statement: BEGIN
2014-05-15 09:14:54 MDT LOG:  statement: INSERT INTO "test" ("val") VALUES (1)
2014-05-15 09:14:54 MDT LOG:  statement: COMMIT
2014-05-15 09:14:54 MDT LOG:  statement: BEGIN
2014-05-15 09:14:54 MDT LOG:  statement: SELECT CURRVAL('"test_pk_seq"')

The problem is there is no COMMIT following that last SELECT, leaving the transaction open. On PostgreSQL this can cause problems _even in other databases on the same server_. See http://www.postgresql.org/message-id/4C6CEE4202000025000348D6@gw.wicourts.gov

I'll submit a pull request with a patch to fix.


Duplicate of #353. The latest pypi release (2.2.4) has the fix.


Confirmed, thanks.
Issue: IntegrityError
Author: tfeldmann
State: closed
Created: 2014-05-15 11:54:47

Example code:

``` python
from peewee import *

database = SqliteDatabase(':memory:', threadlocals=True)


class BaseModel(Model):
    class Meta:
        database = database


class Group(BaseModel):
    name = IntegerField()
    _samples = None

    def samples(self):
        """Samples are generated the first time they are requested"""
        if self._samples is None:
            self._samples = [Sample(group=self) for _ in range(10)]
        return self._samples

    def __repr__(self):
        return '<Group(name={})>'.format(self.name)


class Sample(BaseModel):
    name = CharField(null=True)
    group = ForeignKeyField(Group)

    def __repr__(self):
        return '<Sample(name="{}", group={})>'.format(self.name, self.group)


Group.create_table()
Sample.create_table()


# This works as expected
# ----------------------
g = Group(name=1)
g.save()
g.samples()[0].name = 'Something'

for sample in g.samples():
    sample.save()


# This doesn't work although the group should have an ID when saved?
# ------------------------------------------------------------------
g = Group(name=2)
g.samples()[0].name = 'Something else'
g.save()

for sample in g.samples():
    sample.save()
```

Maybe I'm doing that wrong, but shouldn't the group have an ID as soon as it is saved?


The issue is that the samples are instantiated before the `Group` has an ID. Peewee looks at the group passed in (`group=self`) and attempts to read an ID off it. Since it has no ID at the time of assignment, you get the error you're seeing. Put the call to `g.save()` before `g.samples()[0].name` and you'll be set.


Thank you for your answer.
Is it possible to make the samples reread the group id?
I want to assign properties to the samples before saving the group itself.
(I think I could work around that by using a transaction, but unfortunately the corresponding code is quite distributed.)


It's just python so you can do whatever you want!

``` python
    def samples(self):
        """Samples are generated the first time they are requested"""
        if self._samples is None:
            self._samples = [Sample() for _ in range(10)]
        for sample in self._samples:
            sample.group = self
        return self._samples
```


 Thanks! :+1:
Didn't think of that.
Issue: Race condition in example
Author: kmarekspartz
State: closed
Created: 2014-05-14 20:57:41

I was trying out peewee and reading through the documentation when I came across a code smell.

The [documentation](http://peewee.readthedocs.org/en/latest/peewee/example.html?#creating-new-objects) gives an example as follows:

``` Python
try:
    user = User.get(User.username == request.form['username'])
    ...
except User.DoesNotExist:
    user = User.create( ... )
    ...
```

This isn't how I [normally](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#eafp-vs-lbyl) see this sort of functionality implemented, due to a race condition where e.g. two clients are both interacting and both successfully determine that a user does not exist before either creates the user, then both create the user.

Generally, I would see something like the following instead, which may be possible in peewee already... I haven't used it enough yet to know how exceptions and uniqueness work. If that's the case, this is just a documentation fix.

``` Python
try:
    user = User.create( ... )
    ...
except User.AlreadyExists:
    user = User.get(User.username == request.form['username'])
    ...
```


That's too bad you found a "code smell".

The example app is meant to be very simple and approachable, especially for someone new to peewee. The fact that it doesn't handle concurrent requests to create a new account was acceptable to me when I wrote it, but I guess that is a code smell.

Since you point it out, I have changed the code smell and also updated due to some changes in flask's session serialization: 5fa6d43f0a806f6b965f8ae3bacaf3e42b2335de .


Thanks! I've been bitten in the past by this exact bug with other libraries because I hadn't seen examples done "correctly". Now I know how to account for this.
Issue: delete_instance() deletes multiple rows in a table
Author: nullism
State: closed
Created: 2014-04-29 17:05:19

Hello, I've poured over the documentation for delete_instance(), but I found no reference for this behavior I'm currently seeing.

I have two models. `Project` and `ProjectBranch`.

`Project` is just a CharField.

`ProjectBranch` is as follows:

``` python
class ProjectBranch(DBModel):

    name = CharField()
    project = ForeignKeyField(Project, related_name='branches')

    class Meta:
        primary_key = CompositeKey('name', 'project')
```

However, when I call `delete_instance()` on any `ProjectBranch()` object, it deletes all rows from the table.

Example:

``` python
print "Current branches: "
print "-"*40
i = 0
for branch in md.ProjectBranch.select():
    i += 1
    print branch.name, branch.project.id

print "Current branch count: ", i

project = md.Project.get(id=1)

branch_foo = md.ProjectBranch.get(name='foo', project=project)
print "Deleting 1 branch: ", branch_foo.name
print "actual delete count: ", branch_foo.delete_instance()

print "Remaining branches: "
print "-"*40
i = 0
for branch in md.ProjectBranch.select():
    i += 1
    print branch.name, branch.project.id

print "Remaining branch count: ", i
```

Output:

```
Current branches: 
----------------------------------------
master 1
test-branch 1
foo 1
Current branch count:  3
Deleting 1 branch:  foo
actual delete count:  3
Remaining branches: 
----------------------------------------
Remaining branch count:  0
```


I added a testcase in deef4531b9fc0c87cbecdec8d059650d6e83936c and it is passing. You may need to upgrade your peewee version. What version are you using currently?


I'm currently on 2.2.2. I'll test with the upgrade ASAP. Thanks for the assistance ;)

```
>>> import peewee
>>> peewee.__version__
'2.2.2'
```


Yup! That totally fixed it. Thanks again!

```
Current branches: 
----------------------------------------
master 1
foo 1
test-branch 1
Current branch count:  3
Deleting 1 branch:  foo
actual delete count:  1
Remaining branches: 
----------------------------------------
master 1
test-branch 1
Remaining branch count:  2
```
Issue: Sqlite and ESCAPE
Author: ticapix
State: closed
Created: 2014-04-28 11:18:20

Hi,

I'm trying to use the LIKE operator to match entries containing underscore '_' and percent '%'.
If I understood correctly the Sqlite doc [1], I have to add the ESCAPE 'my escape char'
The common escape char is '\' (I saw '!' too in some online examples)

```
sqlite> SELECT 't_t' LIKE 't\_t' ESCAPE '\';
1
sqlite> SELECT 'tft' LIKE 't\_t' ESCAPE '\';
0
```

Is there a way to register a new operator that add  the ESCAPE clause or override the contains function ?
[1] http://www.sqlite.org/lang_expr.html#like


You can put together a clause:

``` python
>>> query = User.select().where(User.username ** Clause('t\_t', SQL("ESCAPE '\\'")))
>>> print query.sql()
('SELECT t1."id", t1."username" FROM "user" AS t1 WHERE (t1."username" LIKE ? ESCAPE \'\\\')', [u't\\_t'])

```
Issue: Count() returns 0 with pagination > 1, else it returns the full result set.
Author: nullism
State: closed
Created: 2014-04-23 22:05:33

Is this expected behavior? It seems strange to me, but I acknowledge that there may be some reason for it which I don't fully understand.

Example:

``` python
def print_commits(commits):
    print "="*20
    total = 0
    for c in commits:
        total += 1
        #print c.id
    print "Total:", total, "Count():", commits.count()


commits = md.Commit.select().paginate(1,5)
print_commits(commits)

commits = md.Commit.select().paginate(2,5)
print_commits(commits)
```

Output:

```
====================
Total: 5 Count(): 8
====================
Total: 3 Count(): 0
```

Expected output:

```
====================
Total: 5 Count(): 5
====================
Total: 3 Count(): 3
```


When performing a LIMIT or OFFSET you need to wrap the call to count:

``` python
Commit.select().paginate(1, 5).count() # 8
Commit.select().paginate(1, 5).wrapped_count(False) # 5
```


Ah understood. I apologize for submitting this. Apparently I assume too much ;)