akumoth/peewee-issues huggingface dataset:
Issue: AttributeError with multiple ForeignKeyField to the same table.
Author: andmart
State: closed
Created: 2013-10-02 14:18:10

Charles,

Here a simple example to reproduce:

``` python
from peewee import *

class Parent(Model):
    name = CharField()

class Student(Model):
    name = CharField()
    father = ForeignKeyField(Parent)
    mother = ForeignKeyField(Parent)
```

```
AttributeError: Foreign key: student.mother related name "student_set" collision with foreign key using same related_name.
```

It seems that peewee tries to make a set with all the references to same table, but there is case where the attributes are different.


Sorry. I forgot to write peewee's version. 2.1.4


This is because there are two foreign keys to the same model on `Student`.  Specify `related_name` attributes (the backref on `Parent`):

``` python
class Student(Model):
    name = CharField()
    father = ForeignKeyField(Parent, related_name='father_students')
    mother = ForeignKeyField(Parent, related_name='mother_students')
```

This is a new error that is raised because both parent fks would use the same backref (`student_set`), which is ambiguous.


But when a large database is generated with Pwiz, related_names are not written, and the models.py is unusable (except if I edit models.py by hand, but it's tedious...)


> But when a large database is generated with Pwiz, related_names are not written, and the models.py is unusable (except if I edit models.py by hand, but it's tedious...)

What would you propose?


As a begginer in ORM, not relevant things I guess :)
Maybe Pwiz could be improved to automatically add "related_name=XXX" statement in those cases?
You are better than me to know if it's relevant or not ^^
For my purposes, I dit by hand on a 2000 lines models file. It's not as long as it sounds, but the problem is that people using pwiz won't know how to solve the problem (maybe a little update on the documentation about this "issue" would be suitable). 


Charles,
could peewee use the attribute name in place of class name to reference to set?


I agree that it would be nice if pwiz generated working models out of the box, no matter the names. Couldn't it simply use the field name of the referenced model to this effect, i.e. set it as a default `related_name`? Whether it's `father_students`, `fathers`, `mother_students` or what not wouldn't really matter since you can always change it when you find it too awkward.


I'll look into it, but I'm going to go out on a limb and say that `pwiz` does a pretty damn good job at what it does.


I agree! I actually just found out about peewee and used it to generate models for quite large existing databases. With search/replace, I had fixed all problems within minutes. I'm already pretty amazed as it is! This is awesome! :-)
Issue: handle error by flashing error msg in admin during data entry
Author: beebek
State: closed
Created: 2013-09-27 07:00:54

```
class Organization(db.Model):
    name = TextField(default="", unique=True)

    def save(self, *args, **kwargs):
        if not self.get_id():  # this is the first time saving
            self.create_folder()
        return super(Organization, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.name

    def create_folder(self):
        if not os.path.exists(get_project_path(), 'forms', self.name):
            os.mkdir(os.path.join(get_project_path(), 'forms', self.name))
```

After solving issue #234, I am into another problem. If the user enters same name, can a message be flashed, stating that the name already exists in flask-peewee admin ?


You will need to implement that yourself by overriding `ModelAdmin.save_model`.
Issue: create a folder during database creation
Author: beebek
State: closed
Created: 2013-09-25 16:59:24

I have a simple model

``` python
class Organization(db.Model):
    name = TextField(default="")
    form_folder = TextField(default="")

    def __unicode__(self):
        return self.name
```

When the user passes the form_folder name, I need to create a folder with the same name. Is it possible to use some constructor and create it?


Edit: fixed formatting


Typically this is something you would do before saving the model to the database:

``` python

org = Organization(form_folder='whatever')
org.save() # actually save to the db, create the folder
```

You would implement this:

``` python

class Organization(db.Model):
    name = TextField(default='')
    form_folder = TextField(default='')

    def save(self, *args, **kwargs):
        if not self.get_id():  # this is the first time saving
            self.create_folder()
        return super(Organization, self).save(*args, **kwargs)
```


Thanks. :)
Issue: Case stmt for peewee
Author: stanegit
State: closed
Created: 2013-09-24 15:08:56

Hi , thx for peewee , can we do CASE() stmt with peewee?


Funny you should ask that!  I've just been looking at making this easier to accomplish.  Currently you have to do some messy stuff with `Clause` and `R`.


I hope you can do "magic" :)


Something like sqlalchemy would be perfecet

case([
                   (CcnDef.w_pci.code,'PCI'),
                   (CcnDef.w_cath.code,'CATH'),
                 ],else_="None").label('PCI_OR_CATH')


Usage is in the testcase, but it is pretty similar to the SQA example you pasted.  Let me know if you have any questions or trouble w/it


Thx when I get chance I'll test it, but look good , as always :)
Issue: update password also while updating the record
Author: beebek
State: closed
Created: 2013-09-23 13:40:25

I have a simple query e.g.
        user = User.update(organization_name=organization_name,
                    username=username,
                    email=email,
                    active=active,
                    admin=admin,
                    created_date=created_date,
                    role=role).where(User.id==int(request.form['user_id']))
    #     user.set_password(request.form['password'])
        user.execute(

Is there any way so that I can update the password. It says

AttributeError: "'UpdateQuery' object has no attribute 'set_password'"

BESIDE THAT,
everything is working fine. Just want to let the user change their password.
Great Thanks


No, `set_password` is a method on the `User` model, but once you call `.update()` you are working with a `Query` object which doesn't have that method.

You can do:

``` python
from flask_peewee.utils import make_password

(User
    .update(
        organization_name=organization_name,
        username=username,
        email=email,
        password=make_password(request.form['password']))
    .where(User.id == int(request.form['id']))
    .execute())
```


Thanks, it was the solution
By the way I'm using flask-peewee as well in one of my project.
Great Works. cheers !!
Issue: db migration
Author: beebek
State: closed
Created: 2013-09-09 06:47:37

It would be great If there is db migration as well.


Peewee has support for simple migrations using postgresql:

http://peewee.readthedocs.org/en/latest/peewee/playhouse.html#basic-schema-migrations

Currently I do not have plans to enhance this module or add support for other database engines.
Issue: Change >> to a NOT IN instead of IS
Author: kolanos
State: closed
Created: 2013-08-29 20:26:22

Since `.where(field << (...)` equates to a `WHERE field IN (...)`, it stands to reason that a `.where(field >> (...)` would equate to `WHERE field NOT IN (...)`.

Then a `.where(field == None)` would equate to `WHERE field IS NULL` and `.where(field != None)` equates to `WHERE field IS NOT NULL`.

Does that not make more sense?


Unfortunately this is not going to change any time soon.  I made a decision a while ago that `IS` would be treated as a separate lookup even if it is only ever used with `NULL`.  Similarly, negation is always handled by the unary negation operator and is not special cased.
Issue: Added kwargs to ModelOptions for further customization
Author: cam-stitt
State: closed
Created: 2013-08-24 17:56:50

This allows people to add more options to the model, for example if used with a serializer that looks for excluded fields:

```
class User(Model):
    class Meta:
        excludes = ['id']
```

The kwargs that would be used is unique for each use case.


I added another commit that removed the forced auto_increment no matter what. I feel like people should be able to set the pk on an item even if there is an auto_increment.


Both of your changes should now be merged in (more or less).  Thank you!
Issue: add auto reconnect in execute_sql
Author: beanyoung
State: closed
Created: 2013-08-23 03:10:24

I use peewee with tornado, and all requests share one database connection, but when something wrong happens with database, the connection will be unavaliable. So I added a `try exception` block in `execute_sql()`, and this works fine for me.


Because `OperationalError` might signify other things than just a closed connection, I'm not too excited about merging this.  Perhaps you can subclass your `Database` class and add this logic yourself?


Check out 51c66e7ed6bcc56940eb39d30c6d9333290e9b55 (and the subsequent commits).  You can now define a `sql_error_handler` on your database subclass, which should hopefully help solve your problem.


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: cookbook: missing execute in atomic update docs
Author: spenthil
State: closed
Created: 2013-08-14 01:46:04


damn that was fast.

![f80b33b86bcb4d7934e879db667d2fbd](https://f.cloud.github.com/assets/110513/959369/a9f3fcd0-0483-11e3-8fd2-174fa8d25e7c.gif)
Issue: Native UUID field
Author: charlierm
State: closed
Created: 2013-07-24 11:07:14

I am unsure as to whether this is suitable, however, it would be beneficial to have a UUID field built into Peewee.

PostgreSQL has a native UUID datatype, it could use this when possible, falling back to char when it's not available. 

UUIDs are popular, it would be lovely to have them built in if only for the convenience!


Check out the `playhouse` package, bundled with peewee, as it has support for postgres' UUID field:

http://peewee.readthedocs.org/en/latest/peewee/playhouse.html#UUIDField


My mistake, Apologies!

Thank you!


No problem, I need to make the playhouse stuff more obvious as there's some pretty fun toys in there!
Issue: Problem with InsertQuery() returning AutoIncremented value
Author: odonnellryan
State: closed
Created: 2013-07-20 18:34:02

I couldn't get InsertQuery to return the AutoIncremented value upon an Execute. It has (only) returned None for me.

Seems to be a problem with this if statement:

if model._meta.auto_increment:

I've replaced it with:

`def last_insert_id(self, cursor, model):
        if not cursor.lastrowid:
            return None
        return cursor.lastrowid`

WARNING/DISCLAIMER: I haven't tested this solution, or am I an expert at Python (by any stretch of the means).

If you believe I'm doing something horribly wrong, please correct me. lastrowid will return 0 value if it can not return the autoincremented value, from what I can tell.

I apologize if I'm mistaken here! New to the open source community. 

Thanks for writing such a great library, guys!


Hey @odonnellryan no need to apologize, thank you for opening the issue.  It seems to me that this would be addressing the effect rather than the cause, which is that your model does not have `auto_increment` set to `True`.  Do you mind sharing the model definition that is causing this problem?

For a small example why I don't like returning the `lastrowid` -- consider if you're using a non-integer primary key... In the following code we insert a row, and give it a primary key of `"one"`, but sqlite will return the rowid as `1` (since it is the first row inserted into the table).

``` python
In [1]: import sqlite3

In [2]: conn=sqlite3.connect(':memory:')

In [3]: curs = conn.cursor()

In [4]: curs.execute('create table foo (id text primary key, data text
Out[4]: <sqlite3.Cursor at 0x21e41f0>

In [5]: res = curs.execute('insert into foo (id, data) values (?, ?)', ['one

In [6]: res.lastrowid
Out[6]: 1
```


Closing pending feedback from @odonnellryan
Issue: Where is Q?
Author: andr0s
State: closed
Created: 2013-07-18 08:16:41

So the docs stated that I can use something like this:
objs = Obj.filter(Q(name='a') | Q(surname='b'))

But when I'm trying to do this, Python simply can't find Q object. I tried to search the source code, but with no luck (found only DQ but not sure it's what I need).

I'm porting some existing Django code to peewee for some reasons, and I was upset to see that the compatibility (beautifully stated in the docs) is broken (?). The bad thing here is that the code relies on building custom filtering a lot, so the Q objects is chained many times, combined in many ways so I'd strongly prefer to avoid any modifications.

I'm using the peewee version installed using pip (not sure what number it is).


If you check, you can see in the notes on upgrading from 1.0 -> 2.0 the API changed and there is no `Q` anymore as the preferred way to query is by referencing the fields directly: http://peewee.readthedocs.org/en/latest/peewee/upgrading.html#upgrading

For backwards compatibility, `.filter()` can be used along with `DQ` (django Q).

So, you should be able to use .filter and DQ in your code but just know that there is a much better API if you want it!


Hmmm ok thanks, but I think it would be better to update the docs... At least, note that Q has been renamed to DQ (I didn't try to use it because I wasn't sure that DQ is not 'delete query' =))


I will add that to the upgrading notes, I just realized I didn't include that!  Sorry for the confusion.


Added to http://peewee.readthedocs.org/en/latest/peewee/upgrading.html#changes-from-version-1-0
Issue: Provide information on escaping and SQL injection
Author: arnuschky
State: closed
Created: 2013-07-15 04:25:09

Unfortunately, there seems to be no mentioning of proper escaping using peewee. Is it done automatically? Do we have to do something? How to protect against SQL injection and similar attacks? It would be useful if this could be mentioned in the docs somewhere.


Thanks! Your issue-resolving efficiency is really great!
Issue: Usage of wildcards corrupted with Field coerce
Author: johnmave126
State: closed
Created: 2013-07-14 14:22:10

Reproduction

``` python
class Sample(Model):
    test = CharField(max_length=3)

Sample.create(test='123')
sq = Sample.select().filter(test__ilike='%123%')
assert sq.count() != 0
```

Root Cause:
Digg into the source code I found following lines:

peewee.py:775

``` python
            if isinstance(expr.lhs, Field):
                conv = expr.lhs
            lhs, lparams = self.parse_expr(expr.lhs, alias_map, conv)
            rhs, rparams = self.parse_expr(expr.rhs, alias_map, conv)
```

peewee.py:830

``` python
        elif conv and p:
            p = [conv.db_value(i) for i in p]
```

peewee.py:487

``` python
    def coerce(self, value):
        value = format_unicode(value or '')
        return value[:self.attributes['max_length']]
```

Since calling db_value of a CharField will call coerce to return a value for database, a CharField with max_length will discard the ending wildcard. Thus the sq in the sample code will compile to a clause like

``` sql
`test` LIKE '%12'
```

where it should be

``` sql
`test` LIKE '%123%'
```

I have no idea how to fix this in a right way. I personally write an alternative of parse_expr to avoid this problem for now.


Please close this issue
I found it duplicate to #212
Issue: Unable to retrieve columns from joined table (PostgreSQL)
Author: SecurityForUs
State: closed
Created: 2013-07-12 18:09:44

I have two PgSQL tables (servers and api) where api.servers_id = servers.id.  Here are my models:

``` python
class Servers(BaseModel):
    id = BigIntegerField(primary_key=True)
    user = ForeignKeyField(Users, cascade=True)
    ipv4 = CharField(max_length=17)
    ipv6 = CharField(max_length=45)
    hostname = CharField(max_length=256)

class Api(BaseModel):
    id = BigIntegerField(primary_key=True)
    private = CharField(max_length=212)
    public = CharField(max_length=31)
    server = ForeignKeyField(Servers, cascade=True)

servers = Servers
api = Api
```

What I'm wanting to do is get API information based on the server id, so I set up my query like this:

``` python
s = servers
a = api

server_info = s.select(
s.id.alias("sid"),s.ipv6.alias("ipv6"),s.hostname.alias("hostname"),s.ipv4.alias("ipv4"),
a.id.alias("aid"),a.private.alias("private"),a.public.alias("public")
).join(a, self.db.JOIN_FULL).where(s.user==self.uid)
```

The problem is server_info records only have the items of the server itself, not of the api fields as well.  This generates this query:

```
SELECT t1."id" AS sid, t1."ipv6" AS ipv6, t1."hostname" AS hostname, t1."ipv4" AS ipv4, t2."id" AS aid, t2."private" AS private, t2."public" AS public FROM "servers" AS t1 FULL JOIN "api" AS t2 ON (t1."id" = t2."server_id") WHERE (t1."user_id" = 1)
```

Which when ran in PgAdmin gives me the results I want, but not here.  None of the a.\* fields are in the results, just the s.*.


Nevermind, I forgot in a join the joined table is in its own attribute.  Closing.
Issue: Wildcard * does not act as "none or some characters", but as "some characters"
Author: arnuschky
State: closed
Created: 2013-07-09 16:37:45

The following select (on SQLite):

   User.select().where(User.name % "_joe_")

does not work if user name is exactly "joe". The wildcard does not act as "none or some characters", but as "some characters". (And thus behaves just like the '+' of regular expressions.)


With SQLite the `%` operator (case-sensitive like) actually uses the `GLOB` operation which is why it requires you use `*` as the wildcard.  The `**` operator (case-insensitive like) uses `LIKE`.  Confusing, right?

Based on this script, I believe the "*" character is matching zero or more.  Does it work for you?

``` python
from peewee import *

db = SqliteDatabase(':memory:')

class TestModel(Model):
    name = CharField()

names = ['foo', 'bar', 'baz']

TestModel.create_table()
for name in names:
    TestModel.create(name=name)

assert TestModel.get(TestModel.name % '*foo*').name == 'foo'
assert TestModel.get(TestModel.name % 'foo*').name == 'foo'
assert TestModel.get(TestModel.name % '*ba*').name in ('bar', 'baz')
```


Try:

```
  name = CharField(max_length=3)
```

PeeWee seems to strip the search string for (including the wildcard) according to the max_length attribute


@arnuschky -- Ahhh, good catch.
Issue: field unique=True doesn't work?
Author: jfmatth
State: closed
Created: 2013-07-06 06:16:57

Running the latest branch, and the following model doesn't create what I think it does, a unique constraint on the field.

```
import peewee

db = peewee.SqliteDatabase("test.db")

class table1(peewee.Model):
    field1 = peewee.CharField(unique=True)
    field2 = peewee.CharField(null=True)

    class Meta:
        database = db   

db.create_table(table1)

(vPython27) C:\Users\jmatthew\Development\settingsmgr>sqlite3 test.db
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .sch
CREATE TABLE "table1" ("id" INTEGER NOT NULL PRIMARY KEY, "field1" VARCHAR(255) NOT NULL, "field2" V
ARCHAR(255));
sqlite>

```

Am i missing anything?  I looked in the source but didn't see anywhere that that field uniqueness was referenced while generating the table create.

Love the library, let me know how i can help

J


Call model.create_table instead. Db method just creates the table while model method creates indexes as well.


thanks, worked great!
Issue: Extend deferred initialization to database kind
Author: panta
State: closed
Created: 2013-06-28 10:45:45

It would be useful in many circumstances to use different database flavors (Sqlite, MySQL, ...) depending on a configuration parameter.

Extending the mechanism of deferred initialization described in:

http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#deferring-initialization

it would be nice to have something like:

```
deferred_db = GenericDatabase()

class SomeModel(Model):
    class Meta:
        database = deferred_db

...
# read config
if config.DB_KIND == 'sqlite':
    deferred_db.setup('sqlite')
    deferred_db.init(config.DB_NAME)
elif config.DB_KIND == 'mysql':
    deferred_db.setup('mysql')
    deferred_db.init(config.DB_NAME, host=config.DB_HOST, port=config.DB_PORT, ...)
else:
    ...
```

or even merge the functionality in the init() method, with a kind keyword argument (which would work when using the GenericDatabase).

Would it be possible or are there any workarounds at this time?


From docstring:

``` python
    from peewee import *
    from playhouse.proxy import Proxy

    database_proxy = Proxy()  # Create a proxy for our db.

    class BaseModel(Model):
        class Meta:
            database = database_proxy  # Use proxy for our DB.

    class User(BaseModel):
        username = CharField()

    # Based on configuration, use a different database.
    if app.config['DEBUG']:
        database = SqliteDatabase('local.db')
    elif app.config['TESTING']:
        database = SqliteDatabase(':memory:')
    else:
        database = PostgresqlDatabase('mega_production_db')

    # Configure our proxy to use the db we specified in config.
    database_proxy.initialize(database)
```


> From docstring:
> 
> ```python
>     from peewee import *
>     from playhouse.proxy import Proxy
> 
>     database_proxy = Proxy()  # Create a proxy for our db.
> 
>     class BaseModel(Model):
>         class Meta:
>             database = database_proxy  # Use proxy for our DB.
> 
>     class User(BaseModel):
>         username = CharField()
> 
>     # Based on configuration, use a different database.
>     if app.config['DEBUG']:
>         database = SqliteDatabase('local.db')
>     elif app.config['TESTING']:
>         database = SqliteDatabase(':memory:')
>     else:
>         database = PostgresqlDatabase('mega_production_db')
> 
>     # Configure our proxy to use the db we specified in config.
>     database_proxy.initialize(database)
> ```

`from playhouse.proxy import Proxy` not found any more...

It's moved into the peewee module: http://docs.peewee-orm.com/en/latest/peewee/api.html#Proxy

```python
from peewee import Proxy
```

Although you probably want to use instead the `DatabaseProxy`:

```python
from peewee import DatabaseProxy
```
Issue: delete() doesn't handle order_by()
Author: panta
State: closed
Created: 2013-06-27 11:03:32

``` python
n_deleted = Log.delete().order_by(Log.when.asc()).limit(n_to_delete)
```

raises the following exception:

```
AttributeError: 'DeleteQuery' object has no attribute 'order_by'
```


Postgresql does not support this, and Sqlite does but only if compiled with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`.  Because it is only MySQL that supports this feature, I am going to pass on fixing it for now.

There have been similar features requests, from which you might be able to get some ideas:
- #146 , adds limit / order by to update queries
- #153 , adds support for limit to update queries

In the future I may attempt to add a compatibility layer, but for now I am going to close this.


Thank you, in the meantime I arrived at the same conclusions too.
I've found multiple other ways to solve the same problem, thanks to peewee flexibility. In case anyone ends here with the same problem, they are:

select() + delete():

``` python
to_delete = Log.select().order_by(Log.when.asc()).limit(n_to_delete)
n_deleted = Log.delete().where(Log.id << to_delete).execute()
```

select() + DeleteQuery():

``` python
dq = DeleteQuery(Log).where(
    Log.id << Log.select().order_by(Log.when.asc()).limit(n_to_delete)
)
n_deleted = dq.execute()
```

raw SQL:

``` python
db.execute_sql("DELETE FROM log WHERE `id` in ( SELECT `id` FROM log ORDER BY `when` DESC LIMIT ? OFFSET ? )", (n_to_delete, max_logs))
```